/******************************************************************************* * Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com) * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License 3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/lgpl.html * ******************************************************************************/ package com.opendoorlogistics.core.geometry; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.HashMap; import com.opendoorlogistics.api.geometry.LatLong; import com.opendoorlogistics.api.geometry.LatLongToScreen; import com.opendoorlogistics.core.gis.map.data.LatLongImpl; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; public abstract class ODLLoadableGeometry extends ODLGeomImpl{ // private final SimpleSoftReferenceMap<Object,Object> cache = new SimpleSoftReferenceMap<>(10); protected volatile HashMap<Object, Rectangle2D> worldBitmapBoundsByZoomLevel; protected volatile HashMap<Object, Point2D> worldBitmapCentroidsByZoomLevel; protected volatile Envelope wgsBounds; protected volatile LatLong wgsCentroid; // public synchronized String toText(){ // if(fullGeometry!=null){ // return fullGeometry.toText(); // } // // return ""; // } // @Override // public synchronized void putInCache(Object cacheKey, Object data){ // cache.put(cacheKey, data); // } // // @Override // public synchronized Object getFromCache(Object cacheKey){ // return cache.get(cacheKey); // } @Override public boolean isLoaded(){ return true; } @Override public synchronized Point2D getWorldBitmapCentroid(LatLongToScreen latLongToScreen){ Point2D ret = null; if(worldBitmapCentroidsByZoomLevel!=null){ ret = worldBitmapCentroidsByZoomLevel.get(latLongToScreen.getZoomHashmapKey()); if(ret!=null){ return ret; } } // Get the wgs centroid if not yet available if(getWGSCentroid()==null){ return null; } // Translate it to world bitmap for this zoom ret = latLongToScreen.getWorldBitmapPixelPosition(wgsCentroid); // Create cache map if not yet existing if(worldBitmapCentroidsByZoomLevel==null){ worldBitmapCentroidsByZoomLevel = new HashMap<>(20); } worldBitmapCentroidsByZoomLevel.put(latLongToScreen.getZoomHashmapKey(), ret); return ret; } @Override public synchronized Rectangle2D getWorldBitmapBounds(LatLongToScreen latLongToScreen){ Rectangle2D ret=null; // Return pre-calculated if we have it if(worldBitmapBoundsByZoomLevel!=null){ ret = worldBitmapBoundsByZoomLevel.get(latLongToScreen.getZoomHashmapKey()); if(ret!=null){ return ret; } } // Get wgs bounds if(getWGSBounds()==null){ return null; } // Convert min and max points remembering x=longitude, y = latitude Point2D min = latLongToScreen.getWorldBitmapPixelPosition(new LatLongImpl(wgsBounds.getMinY(), wgsBounds.getMinX())); Point2D max = latLongToScreen.getWorldBitmapPixelPosition(new LatLongImpl(wgsBounds.getMaxY(), wgsBounds.getMaxX())); // I'm not sure if the coordinate directions might flip so I'm playing it safe here double minX = Math.min(min.getX(), max.getX()); double minY = Math.min(min.getY(), max.getY()); double maxX = Math.max(min.getX(), max.getX()); double maxY = Math.max(min.getY(), max.getY()); // Get bounding rectangle ret = new Rectangle2D.Double(minX,minY, maxX - minX , maxY - minY); // Cache it if(worldBitmapBoundsByZoomLevel==null){ // OSM has 20 zoom levels by default worldBitmapBoundsByZoomLevel = new HashMap<>(20); } worldBitmapBoundsByZoomLevel.put(latLongToScreen.getZoomHashmapKey(), ret); return ret; } @Override public synchronized String toText(){ Geometry g = getJTSGeometry(); if(g!=null){ return g.toText(); } return ""; } }