Skip to content

Commit

Permalink
Change VectorTileBuilder.addFeature() signature to simplify and clari…
Browse files Browse the repository at this point in the history
…fy implementations.

Avoid duplicated code, make it clear what geometry to encode.
  • Loading branch information
Gabriel Roldan committed Jun 28, 2015
1 parent 3b38b1a commit b00b4fb
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 132 deletions.
Expand Up @@ -7,7 +7,7 @@
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.util.List; import java.util.Map;


import javax.measure.unit.SI; import javax.measure.unit.SI;
import javax.measure.unit.Unit; import javax.measure.unit.Unit;
Expand All @@ -20,16 +20,10 @@
import org.geoserver.wms.vector.VectorTileBuilder; import org.geoserver.wms.vector.VectorTileBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS; import org.geotools.referencing.CRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.CoordinateReferenceSystem;


import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.PrecisionModel; import com.vividsolutions.jts.geom.PrecisionModel;
import com.vividsolutions.jts.precision.CoordinatePrecisionReducerFilter; import com.vividsolutions.jts.precision.CoordinatePrecisionReducerFilter;


Expand Down Expand Up @@ -73,67 +67,36 @@ public GeoJsonWMSBuilder(Rectangle mapSize, ReferencedEnvelope mapArea) {
} }


@Override @Override
public void addFeature(SimpleFeature feature) { public void addFeature(String layerName, String featureId, String geometryName, Geometry aGeom,
Map<String, Object> properties) {


final SimpleFeatureType fType = feature.getFeatureType();
final GeometryDescriptor defaultGeomType = fType.getGeometryDescriptor();
Preconditions.checkNotNull(defaultGeomType);

Geometry aGeom = (Geometry) feature.getDefaultGeometry();
if (aGeom == null) {
return;
}
if (aGeom instanceof GeometryCollection && aGeom.getNumGeometries() == 1) {
aGeom = aGeom.getGeometryN(0);
}
if (precisionReducerFilter != null) { if (precisionReducerFilter != null) {
aGeom.apply(precisionReducerFilter); aGeom.apply(precisionReducerFilter);
} }


jsonWriter.object(); jsonWriter.object();
jsonWriter.key("type").value("Feature"); jsonWriter.key("type").value("Feature");


List<AttributeDescriptor> types = fType.getAttributeDescriptors(); jsonWriter.key("id").value(featureId);

jsonWriter.key("id").value(feature.getID());


jsonWriter.key("geometry"); jsonWriter.key("geometry");


// Write the geometry, whether it is a null or not // Write the geometry, whether it is a null or not
jsonWriter.writeGeom(aGeom); jsonWriter.writeGeom(aGeom);
jsonWriter.key("geometry_name").value(defaultGeomType.getLocalName()); jsonWriter.key("geometry_name").value(geometryName);


jsonWriter.key("properties"); jsonWriter.key("properties");
jsonWriter.object(); jsonWriter.object();


for (int j = 0; j < types.size(); j++) { for (Map.Entry<String, Object> e : properties.entrySet()) {
Object value = feature.getAttribute(j); String attributeName = e.getKey();
AttributeDescriptor attributeDescriptor = types.get(j); Object value = e.getValue();

if (value != null) {
if (value instanceof Geometry) {
// This is an area of the spec where they
// decided to 'let convention evolve',
// that is how to handle multiple
// geometries. My take is to print the
// geometry here if it's not the default.
// If it's the default that you already
// printed above, so you don't need it here.
if (attributeDescriptor.equals(defaultGeomType)) {
// Do nothing, we wrote it above
// jsonWriter.value("geometry_name");
} else {
jsonWriter.key(attributeDescriptor.getLocalName());
jsonWriter.writeGeom((Geometry) value);
}
} else {
jsonWriter.key(attributeDescriptor.getLocalName());
jsonWriter.value(value);
}


} else { jsonWriter.key(attributeName);
jsonWriter.key(attributeDescriptor.getLocalName()); if (value == null) {
jsonWriter.value(null); jsonWriter.value(null);
} else {
jsonWriter.value(value);
} }
} }


Expand Down Expand Up @@ -165,5 +128,4 @@ public WebMap build(WMSMapContent mapContent) throws IOException {


return map; return map;
} }

} }
Expand Up @@ -4,9 +4,6 @@


import java.awt.Rectangle; import java.awt.Rectangle;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;


import no.ecc.vectortile.VectorTileEncoder; import no.ecc.vectortile.VectorTileEncoder;
Expand All @@ -16,8 +13,6 @@
import org.geoserver.wms.map.RawMap; import org.geoserver.wms.map.RawMap;
import org.geoserver.wms.vector.VectorTileBuilder; import org.geoserver.wms.vector.VectorTileBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;


import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Geometry;


Expand All @@ -37,28 +32,14 @@ public MapBoxTileBuilder(Rectangle mapSize, ReferencedEnvelope mapArea) {
} }


@Override @Override
public void addFeature(SimpleFeature feature) { public void addFeature(String layerName, String featureId, String geometryName,
String layerName = feature.getFeatureType().getTypeName(); Geometry geometry, Map<String, Object> properties) {
Map<String, ?> attributes = propertiesToAttributes(feature.getProperties());
Geometry geometry = (Geometry) feature.getDefaultGeometry();
encoder.addFeature(layerName, attributes, geometry);
}


protected Map<String, Object> propertiesToAttributes(Collection<Property> properties) { encoder.addFeature(layerName, properties, geometry);
Map<String, Object> attributes = new HashMap<String, Object>();
Iterator<Property> it = properties.iterator();
while (it.hasNext()) {
Property property = it.next();
if (!(property.getValue() instanceof Geometry)) {
attributes.put(property.getName().getLocalPart(), property.getValue());
}
}
return attributes;
} }


@Override @Override
public WebMap build(WMSMapContent mapContent) throws IOException { public WebMap build(WMSMapContent mapContent) throws IOException {

byte[] contents = encoder.encode(); byte[] contents = encoder.encode();
return new RawMap(mapContent, contents, MIME_TYPE); return new RawMap(mapContent, contents, MIME_TYPE);
} }
Expand Down
Expand Up @@ -25,12 +25,6 @@
import org.geoserver.wms.vector.VectorTileBuilder; import org.geoserver.wms.vector.VectorTileBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.renderer.lite.RendererUtilities; import org.geotools.renderer.lite.RendererUtilities;
import org.opengis.feature.Attribute;
import org.opengis.feature.ComplexAttribute;
import org.opengis.feature.Feature;
import org.opengis.feature.GeometryAttribute;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.geometry.MismatchedDimensionException; import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.operation.TransformException; import org.opengis.referencing.operation.TransformException;


Expand Down Expand Up @@ -77,18 +71,18 @@ public TopologyBuilder(Rectangle mapSize, ReferencedEnvelope mapArea) {
} }


@Override @Override
public void addFeature(SimpleFeature feature) { public void addFeature(String layerName, String featureId, String geometryName,
String layer = feature.getName().getLocalPart(); Geometry geometry, Map<String, Object> properties) {
TopoGeom topoObj; TopoGeom topoObj;
try { try {
topoObj = createObject(feature); topoObj = createObject(featureId, geometry, properties);
} catch (MismatchedDimensionException | TransformException e) { } catch (MismatchedDimensionException | TransformException e) {
e.printStackTrace(); e.printStackTrace();
throw Throwables.propagate(e); throw Throwables.propagate(e);
} }


if (topoObj != null) { if (topoObj != null) {
layers.put(layer, topoObj); layers.put(layerName, topoObj);
} }
} }


Expand Down Expand Up @@ -135,19 +129,8 @@ public RawMap build(WMSMapContent mapContent) throws IOException {
} }


@Nullable @Nullable
private TopoGeom createObject(Feature feature) throws MismatchedDimensionException, private TopoGeom createObject(String featureId, Geometry geom, Map<String, Object> properties)
TransformException { throws MismatchedDimensionException, TransformException {
Geometry geom;
{// ignore geometry-less features
GeometryAttribute defaultGeometryProperty = feature.getDefaultGeometryProperty();
if (null == defaultGeometryProperty) {
return null;
}
geom = (Geometry) defaultGeometryProperty.getValue();
if (geom == null) {
return null;
}
}


// // snap to pixel // // snap to pixel
geom = fixedGeometryFactory.createGeometry(geom); geom = fixedGeometryFactory.createGeometry(geom);
Expand All @@ -161,33 +144,13 @@ private TopoGeom createObject(Feature feature) throws MismatchedDimensionExcepti
} }


TopoGeom geometry = createGeometry(geom); TopoGeom geometry = createGeometry(geom);
Map<String, Object> properties = getProperties(feature);
geometry.setProperties(properties); geometry.setProperties(properties);


geometry.setId(feature.getIdentifier().getID()); geometry.setId(featureId);
return geometry; return geometry;
} }


private Map<String, Object> getProperties(ComplexAttribute feature) {
Map<String, Object> props = new HashMap<>();
for (Property p : feature.getProperties()) {
if (!(p instanceof Attribute) || (p instanceof GeometryAttribute)) {
continue;
}
String name = p.getName().getLocalPart();
Object value;
if (p instanceof ComplexAttribute) {
value = getProperties((ComplexAttribute) p);
} else {
value = p.getValue();
}
if (value != null) {
props.put(name, value);
}
}
return props;
}

private TopoGeom createGeometry(Geometry geom) { private TopoGeom createGeometry(Geometry geom) {
Preconditions.checkNotNull(geom); Preconditions.checkNotNull(geom);


Expand Down
@@ -1,14 +1,17 @@
package org.geoserver.wms.vector; package org.geoserver.wms.vector;


import java.io.IOException; import java.io.IOException;
import java.util.Map;


import org.geoserver.wms.WMSMapContent; import org.geoserver.wms.WMSMapContent;
import org.geoserver.wms.WebMap; import org.geoserver.wms.WebMap;
import org.opengis.feature.simple.SimpleFeature;
import com.vividsolutions.jts.geom.Geometry;


public interface VectorTileBuilder { public interface VectorTileBuilder {


void addFeature(SimpleFeature feature); void addFeature(String layerName, String featureId, String geometryName, Geometry geometry,
Map<String, Object> properties);


WebMap build(WMSMapContent mapContent) throws IOException; WebMap build(WMSMapContent mapContent) throws IOException;


Expand Down

0 comments on commit b00b4fb

Please sign in to comment.