/******************************************************************************* * Copyright 2012 Geoscience Australia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package au.gov.ga.earthsci.worldwind.common.layers.shapefile.surfaceshape; import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.avlist.AVList; import gov.nasa.worldwind.avlist.AVListImpl; import gov.nasa.worldwind.formats.shapefile.Shapefile; import gov.nasa.worldwind.geom.Sector; import gov.nasa.worldwind.layers.AbstractLayer; import gov.nasa.worldwind.layers.Layer; import gov.nasa.worldwind.layers.RenderableLayer; import gov.nasa.worldwind.render.BasicShapeAttributes; import gov.nasa.worldwind.render.Material; import gov.nasa.worldwind.render.Renderable; import gov.nasa.worldwind.render.ShapeAttributes; import gov.nasa.worldwind.render.SurfaceShape; import gov.nasa.worldwind.util.Logging; import gov.nasa.worldwind.util.WWXML; import gov.nasa.worldwindx.examples.util.ShapefileLoader; import java.awt.Color; import java.net.MalformedURLException; import java.net.URL; import javax.xml.xpath.XPath; import org.w3c.dom.Element; import au.gov.ga.earthsci.worldwind.common.util.AVKeyMore; /** * Layer factory which creates a {@link Layer} from an AVList or XML element. * The parameters must contain a URL which points to a ESRI shapefile. */ public class ShapefileLayerFactory { /** * Create a new {@link Layer}. * * @param params * Parameters describing the layer * @return A new {@link Layer} */ public static Layer createLayer(AVList params) { String s = params.getStringValue(AVKey.URL); if (s == null) { String message = "Shapefile URL not specified"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } URL context = (URL) params.getValue(AVKeyMore.CONTEXT_URL); URL url; try { url = new URL(context, s); } catch (MalformedURLException e) { String message = "Shapefile URL malformed"; Logging.logger().severe(message); throw new IllegalArgumentException(message); } //read the shapefile, and use the standard ShapefileLoader to create a layer Shapefile shapefile = new UrlShapefile(url); Layer layer = new ShapefileLoader().createLayerFromShapefile(shapefile); //set the sector parameter so that the extents can be zoomed to if (params.getValue(AVKey.SECTOR) == null) { layer.setValue(AVKey.SECTOR, Sector.fromDegrees(shapefile.getBoundingRectangle())); } s = params.getStringValue(AVKey.DISPLAY_NAME); if (s != null) { layer.setName(s); } Long l = (Long) params.getValue(AVKey.EXPIRY_TIME); if (l != null) { layer.setExpiryTime(l); } //set the shape drawing attributes ShapeAttributes attributes = new BasicShapeAttributes(); setAttributesFromParams(attributes, params); //also set the attributes on any renderables within the layer if (layer instanceof RenderableLayer) { RenderableLayer rl = (RenderableLayer) layer; for (Renderable renderable : rl.getRenderables()) { if (renderable instanceof SurfaceShape) { ((SurfaceShape) renderable).setAttributes(attributes); } } } //disable picking by default layer.setPickEnabled(false); return layer; } /** * Create a new {@link Layer} from an XML definition. * * @param domElement * XML element * @param params * Extra parameters describing the layer * @return A new {@link Layer} */ public static Layer createLayer(Element domElement, AVList params) { if (params == null) { params = new AVListImpl(); } XPath xpath = WWXML.makeXPath(); AbstractLayer.getLayerConfigParams(domElement, params); getAttributeParams(domElement, params); WWXML.checkAndSetStringParam(domElement, params, AVKey.URL, "URL", xpath); return createLayer(params); } /** * Put any shape drawing attributes defined in the AVList into the * attributes. * * @param attributes * Destination attributes object * @param params * Source parameters */ protected static void setAttributesFromParams(ShapeAttributes attributes, AVList params) { Boolean b = (Boolean) params.getValue(ShapeAttributeKey.DRAW_INTERIOR); if (b != null) { attributes.setDrawInterior(b); } b = (Boolean) params.getValue(ShapeAttributeKey.DRAW_OUTLINE); if (b != null) { attributes.setDrawOutline(b); } b = (Boolean) params.getValue(ShapeAttributeKey.ANTIALIASING); if (b != null) { attributes.setEnableAntialiasing(b); } Color c = (Color) params.getValue(ShapeAttributeKey.INTERIOR_COLOR); if (c != null) { attributes.setInteriorMaterial(new Material(c)); } c = (Color) params.getValue(ShapeAttributeKey.OUTLINE_COLOR); if (c != null) { attributes.setOutlineMaterial(new Material(c)); } Double d = (Double) params.getValue(ShapeAttributeKey.INTERIOR_OPACITY); if (d != null) { attributes.setInteriorOpacity(d); } d = (Double) params.getValue(ShapeAttributeKey.OUTLINE_OPACITY); if (d != null) { attributes.setOutlineOpacity(d); } d = (Double) params.getValue(ShapeAttributeKey.OUTLINE_WIDTH); if (d != null) { attributes.setOutlineWidth(d); } Integer i = (Integer) params.getValue(ShapeAttributeKey.STIPPLE_FACTOR); if (i != null) { attributes.setOutlineStippleFactor(i); } i = (Integer) params.getValue(ShapeAttributeKey.STIPPLE_PATTERN); if (i != null) { attributes.setOutlineStipplePattern(i.shortValue()); } } /** * Pull any shape drawing attributes from an XML element and store them in * the AVList. * * @param domElement * Source XML element * @param params * Destination AVList * @return params */ protected static AVList getAttributeParams(Element domElement, AVList params) { if (params == null) { params = new AVListImpl(); } XPath xpath = WWXML.makeXPath(); WWXML.checkAndSetBooleanParam(domElement, params, ShapeAttributeKey.DRAW_INTERIOR, "DrawInterior", xpath); WWXML.checkAndSetBooleanParam(domElement, params, ShapeAttributeKey.DRAW_OUTLINE, "DrawOutline", xpath); WWXML.checkAndSetBooleanParam(domElement, params, ShapeAttributeKey.ANTIALIASING, "Antialiasing", xpath); WWXML.checkAndSetColorParam(domElement, params, ShapeAttributeKey.INTERIOR_COLOR, "InteriorColor", xpath); WWXML.checkAndSetColorParam(domElement, params, ShapeAttributeKey.OUTLINE_COLOR, "OutlineColor", xpath); WWXML.checkAndSetDoubleParam(domElement, params, ShapeAttributeKey.INTERIOR_OPACITY, "InteriorOpacity", xpath); WWXML.checkAndSetDoubleParam(domElement, params, ShapeAttributeKey.OUTLINE_OPACITY, "OutlineOpacity", xpath); WWXML.checkAndSetDoubleParam(domElement, params, ShapeAttributeKey.OUTLINE_WIDTH, "OutlineWidth", xpath); WWXML.checkAndSetIntegerParam(domElement, params, ShapeAttributeKey.STIPPLE_FACTOR, "StippleFactor", xpath); WWXML.checkAndSetIntegerParam(domElement, params, ShapeAttributeKey.STIPPLE_PATTERN, "StipplePattern", xpath); return params; } }