placenamelayer.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,493 行 · 第 1/4 页
JAVA
1,493 行
{
String msg = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
return (int) ((latitude.getDegrees() + 90d) / delta.getDegrees());
}
static int computeColumn(Angle delta, Angle longitude)
{
if (delta == null || longitude == null)
{
String msg = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
return (int) ((longitude.getDegrees() + 180d) / delta.getDegrees());
}
static Angle computeRowLatitude(int row, Angle delta)
{
if (delta == null)
{
String msg = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
return Angle.fromDegrees(-90d + delta.getDegrees() * row);
}
static Angle computeColumnLongitude(int column, Angle delta)
{
if (delta == null)
{
String msg = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
return Angle.fromDegrees(-180 + delta.getDegrees() * column);
}
public Integer getHashInt()
{
return hashInt;
}
int computeHash()
{
return this.getFileCachePath() != null ? this.getFileCachePath().hashCode() : 0;
}
@Override
public boolean equals(Object o)
{
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final Tile tile = (Tile) o;
return !(this.getFileCachePath() != null ? !this.getFileCachePath().equals(tile.getFileCachePath()) : tile.getFileCachePath() != null);
}
String getFileCachePath()
{
if (this.fileCachePath == null)
this.fileCachePath = this.placeNameService.createFileCachePathFromTile(this.row, this.column);
return this.fileCachePath;
}
PlaceNameService getPlaceNameService()
{
return placeNameService;
}
java.net.URL getRequestURL() throws java.net.MalformedURLException
{
return this.placeNameService.createServiceURLFromSector(this.sector);
}
Sector getSector()
{
return sector;
}
public int hashCode()
{
return this.hashInt;
}
boolean isTileInMemoryWithData()
{
//todo switched to string
Tile t = (Tile) WorldWind.getMemoryCache(Tile.class.getName()).getObject(this.getHashInt());
if (t ==null || t.getDataChunk() == null)
return false;
else
return true;
}
public boolean isTileLocalOrAbsent()
{
if (this.getPlaceNameService().isResourceAbsent(
this.getPlaceNameService().getTileNumber(this.row, this.column)))
return true; // tile is absent
URL url = WorldWind.getDataFileStore().findFile(this.getFileCachePath(), false);
return url != null; // tile is already in cache
}
public Vec4 getCentroidPoint(Globe globe)
{
if (globe == null)
{
String msg = Logging.getMessage("nullValue.GlobeIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (this.centroid == null)
{
LatLon c = this.getSector().getCentroid();
this.centroid = globe.computePointFromPosition(c.getLatitude(), c.getLongitude(), 0);
}
return this.centroid;
}
public double getPriority()
{
return priority;
}
public void setPriority(double priority)
{
this.priority = priority;
}
}
private Tile[] buildTiles(PlaceNameService placeNameService, NavigationTile navTile)
{
final Angle dLat = placeNameService.getTileDelta().getLatitude();
final Angle dLon = placeNameService.getTileDelta().getLongitude();
// Determine the row and column offset from the global tiling origin for the southwest tile corner
int firstRow = Tile.computeRow(dLat, navTile.navSector.getMinLatitude());
int firstCol = Tile.computeColumn(dLon, navTile.navSector.getMinLongitude());
int lastRow = Tile.computeRow(dLat, navTile.navSector.getMaxLatitude().subtract(dLat));
int lastCol = Tile.computeColumn(dLon, navTile.navSector.getMaxLongitude().subtract(dLon));
int nLatTiles = lastRow - firstRow + 1;
int nLonTiles = lastCol - firstCol + 1;
Tile[] tiles = new Tile[nLatTiles * nLonTiles];
Angle p1 = Tile.computeRowLatitude(firstRow, dLat);
for (int row = 0; row <= lastRow-firstRow; row++)
{
Angle p2;
p2 = p1.add(dLat);
Angle t1 = Tile.computeColumnLongitude(firstCol, dLon);
for (int col = 0; col <= lastCol-firstCol; col++)
{
Angle t2;
t2 = t1.add(dLon);
//Need offset row and column to correspond to total ro/col numbering
tiles[col + row * nLonTiles] = new Tile(placeNameService, new Sector(p1, p2, t1, t2), row+firstRow, col+firstCol);
t1 = t2;
}
p1 = p2;
}
return tiles;
}
// ============== Place Name Data Structures ======================= //
// ============== Place Name Data Structures ======================= //
// ============== Place Name Data Structures ======================= //
private static class PlaceNameChunk implements Cacheable
{
final PlaceNameService placeNameService;
final CharBuffer textArray;
final int[] textIndexArray;
final double[] latlonArray;
final int numEntries;
final long estimatedMemorySize;
PlaceNameChunk(PlaceNameService service, CharBuffer text, int[] textIndices,
double[] positions, int numEntries)
{
this.placeNameService = service;
this.textArray = text;
this.textIndexArray = textIndices;
this.latlonArray = positions;
this.numEntries = numEntries;
this.estimatedMemorySize = this.computeEstimatedMemorySize();
}
long computeEstimatedMemorySize()
{
long result = 0;
if (!textArray.isDirect())
result += (Character.SIZE / 8) * textArray.capacity();
result += (Integer.SIZE / 8) * textIndexArray.length;
result += (Double.SIZE / 8) * latlonArray.length;
return result;
}
Position getPosition(int index)
{
int latlonIndex = 2 * index;
return Position.fromDegrees(latlonArray[latlonIndex], latlonArray[latlonIndex + 1], 0);
}
PlaceNameService getPlaceNameService()
{
return this.placeNameService;
}
CharSequence getText(int index)
{
int beginIndex = textIndexArray[index];
int endIndex = (index + 1 < numEntries) ? textIndexArray[index + 1] : textArray.length();
return this.textArray.subSequence(beginIndex, endIndex);
}
public long getSizeInBytes()
{
return this.estimatedMemorySize;
}
private Iterable<GeographicText> makeIterable(DrawContext dc)
{
//get dispay dist for this service for use in label annealing
double maxDisplayDistance = this.getPlaceNameService().getMaxDisplayDistance();
ArrayList<GeographicText> list = new ArrayList<GeographicText>();
for (int i = 0; i < this.numEntries; i++)
{
CharSequence str = getText(i);
Position pos = getPosition(i);
GeographicText text = new UserFacingText(str, pos);
text.setFont(this.placeNameService.getFont());
text.setColor(this.placeNameService.getColor());
text.setBackgroundColor(this.placeNameService.getBackgroundColor());
text.setVisible(isNameVisible(dc, this.placeNameService, pos));
text.setPriority(maxDisplayDistance);
list.add(text);
}
return list;
}
}
// ============== Rendering ======================= //
// ============== Rendering ======================= //
// ============== Rendering ======================= //
private final GeographicTextRenderer placeNameRenderer = new GeographicTextRenderer();
@Override
protected void doRender(DrawContext dc)
{
this.referencePoint = this.computeReferencePoint(dc);
int serviceCount = this.placeNameServiceSet.getServiceCount();
for (int i = 0; i < serviceCount; i++)
{
PlaceNameService placeNameService = this.placeNameServiceSet.getService(i);
if (!isServiceVisible(dc, placeNameService))
continue;
double minDistSquared = placeNameService.getMinDisplayDistance() * placeNameService.getMinDisplayDistance();
double maxDistSquared = placeNameService.getMaxDisplayDistance() * placeNameService.getMaxDisplayDistance();
if (isSectorVisible(dc, placeNameService.getMaskingSector(), minDistSquared, maxDistSquared))
{
ArrayList<Tile> baseTiles = new ArrayList<Tile>();
NavigationTile navTile = this.navTiles.get(i);
//drill down into tiles to find bottom level navTiles visible
List<NavigationTile> list=navTile.navTilesVisible(dc, minDistSquared, maxDistSquared);
for(NavigationTile nt: list)
{
baseTiles.addAll(nt.getTiles());
}
for (Tile tile : baseTiles)
{
try
{
drawOrRequestTile(dc, tile, minDistSquared, maxDistSquared);
}
catch (Exception e)
{
Logging.logger().log(Level.FINE, Logging.getMessage("layers.PlaceNameLayer.ExceptionRenderingTile"),
e);
}
}
}
}
this.sendRequests();
this.requestQ.clear();
}
private Vec4 computeReferencePoint(DrawContext dc)
{
if (dc.getViewportCenterPosition() != null)
return dc.getGlobe().computePointFromPosition(dc.getViewportCenterPosition());
java.awt.geom.Rectangle2D viewport = dc.getView().getViewport();
int x = (int) viewport.getWidth() / 2;
for (int y = (int) (0.5 * viewport.getHeight()); y >= 0; y--)
{
Position pos = dc.getView().computePositionFromScreenPoint(x, y);
if (pos == null)
continue;
return dc.getGlobe().computePointFromPosition(pos.getLatitude(), pos.getLongitude(), 0d);
}
return null;
}
protected Vec4 getReferencePoint()
{
return this.referencePoint;
}
private void drawOrRequestTile(DrawContext dc, Tile tile, double minDisplayDistanceSquared,
double maxDisplayDistanceSquared)
{
if (!isTileVisible(dc, tile, minDisplayDistanceSquared, maxDisplayDistanceSquared))
return;
if (tile.isTileInMemoryWithData())
{
PlaceNameChunk placeNameChunk = tile.getDataChunk();
if (placeNameChunk.numEntries > 0)
{
Iterable<GeographicText> renderIter = placeNameChunk.makeIterable(dc);
this.placeNameRenderer.render(dc, renderIter);
}
return;
}
// Tile's data isn't available, so request it
if (!tile.getPlaceNameService().isResourceAbsent(tile.getPlaceNameService().getTileNumber(
tile.row, tile.column)))
{
this.requestTile(dc, tile);
}
}
private static boolean isServiceVisible(DrawContext dc, PlaceNameService placeNameService)
{
if (!placeNameService.isEnabled())
return false;
//noinspection SimplifiableIfStatement
if (dc.getVisibleSector() != null && !placeNameService.getMaskingSector().intersects(dc.getVisibleSector()))
return false;
return placeNameService.getExtent(dc).intersects(dc.getView().getFrustumInModelCoordinates());
}
private static boolean isSectorVisible(DrawContext dc, Sector sector, double minDistanceSquared,
double maxDistanceSquared)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?