package com.nutiteq.kml; import com.nutiteq.components.WgsBoundingBox; import com.nutiteq.components.WgsPoint; import com.nutiteq.utils.Utils; /** * <p> * Basic KML URL reader, adds standard BBOX, zoom and max=10 parameters in * default way. Usage example with MapItem:<br/> * * <code>mapItem.addKmlService(new KmlUrlReader("http://www.panoramio.com/panoramio.kml?LANG=en_US.utf8&",true));</code> * </p> */ public class KmlUrlReader implements KmlService { private static final String DEFAULT_KML_ICON = "/images/def_kml.png"; private final String url; private final boolean needsUpdateAfterRead; private boolean hasBeenRead; private int lastReadZoom; private WgsPoint lastReadCenter; private WgsPoint screenSizeDegrees; private final int maxElements; private final boolean serverSideRender; private String defaultIcon; /** * * Constructor for the built-in KML reader. Asks for 10 items. * * @param kmlUrl * URL where to read the KML * @param needsUpdateAfterRead * true if KML service is dynamic (in time and regarding BBOX), false * otherwise */ public KmlUrlReader(final String kmlUrl, final boolean needsUpdateAfterRead) { this(kmlUrl, 10, needsUpdateAfterRead, false); } /** * Constructor for the built-in KML reader. * * @param kmlUrl * URL where to read the KML * @param maxElements * how many elements to request from server. * @param needsUpdateAfterRead * true if KML service is dynamic (in time and regarding BBOX), false * otherwise */ public KmlUrlReader(final String kmlUrl, final int maxElements, final boolean needsUpdateAfterRead) { this(kmlUrl, maxElements, needsUpdateAfterRead, false); } /** * Constructor for the built-in KML reader. * * @param kmlUrl * URL where to read the KML * @param maxElements * how many elements to request from server. * @param needsUpdateAfterRead * true if KML service is dynamic (in time and regarding BBOX), false * otherwise * @param defaultIcon * default marker image location for the KML places */ public KmlUrlReader(final String kmlUrl, final int maxElements, final boolean needsUpdateAfterRead, final String defaultIcon) { this(kmlUrl, maxElements, needsUpdateAfterRead, false,defaultIcon); } /** * Constructor for the built-in KML reader. * * @param kmlUrl * URL where to read the KML * @param maxElements * how many elements to request from server. * @param needsUpdateAfterRead * true if KML service is dynamic (in time and regarding BBOX), false * otherwise * @param serverSideRender * are elements drawn on map server side */ public KmlUrlReader(final String kmlUrl, final int maxElements, final boolean needsUpdateAfterRead, final boolean serverSideRender) { this(kmlUrl, maxElements, needsUpdateAfterRead, serverSideRender,DEFAULT_KML_ICON); } /** * Constructor for the built-in KML reader. * * @param kmlUrl * URL where to read the KML * @param maxElements * how many elements to request from server. * @param needsUpdateAfterRead * true if KML service is dynamic (in time and regarding BBOX), false * otherwise * @param serverSideRender * are elements drawn on map server side */ public KmlUrlReader(final String kmlUrl, final int maxElements, final boolean needsUpdateAfterRead, final boolean serverSideRender, final String defaultIcon) { url = needsUpdateAfterRead ? Utils.prepareForParameters(kmlUrl) : kmlUrl; this.maxElements = maxElements; this.needsUpdateAfterRead = needsUpdateAfterRead; this.serverSideRender = serverSideRender; this.defaultIcon = defaultIcon; } public String getDefaultIcon() { return defaultIcon; } public String getServiceUrl(final WgsBoundingBox boundingBox, final int zoom) { final StringBuffer serviceUrl = new StringBuffer(url); if (needsUpdateAfterRead) { serviceUrl.append("BBOX=").append(boundingBox.getWgsMin().getLon()).append(","); serviceUrl.append(boundingBox.getWgsMin().getLat()).append(","); serviceUrl.append(boundingBox.getWgsMax().getLon()).append(","); serviceUrl.append(boundingBox.getWgsMax().getLat()); serviceUrl.append("&zoom=").append(zoom).append("&max=").append(maxElements); } lastReadZoom = zoom; hasBeenRead = true; final double screenWidth = Math.abs(boundingBox.getWgsMax().getLon() - boundingBox.getWgsMin().getLon()); final double screenHeight = Math.abs(boundingBox.getWgsMax().getLat() - boundingBox.getWgsMin().getLat()); screenSizeDegrees = new WgsPoint(screenWidth, screenHeight); lastReadCenter = boundingBox.getBoundingBoxCenter(); return serviceUrl.toString(); } public int maxResults() { return maxElements; } public boolean needsUpdate(final WgsBoundingBox boundingBox, final int zoom) { if (!hasBeenRead) { return true; } if (!needsUpdateAfterRead) { return false; } if (lastReadZoom != zoom) { return true; } final WgsPoint bBoxCenter = boundingBox.getBoundingBoxCenter(); final double xChange = Math.abs(lastReadCenter.getLon() - bBoxCenter.getLon()); final double yChange = Math.abs(lastReadCenter.getLat() - bBoxCenter.getLat()); //if screen moved 1/5 of screen size, update return xChange >= (screenSizeDegrees.getLon() * 0.20) || yChange >= (screenSizeDegrees.getLat() * 0.20); } public void resetRead() { hasBeenRead = false; } public boolean serverSideRender() { return serverSideRender; } }