/gazetteer/src/main/java/org/ala/rest/GazetteerFeature.java

http://alageospatialportal.googlecode.com/ · Java · 210 lines · 145 code · 42 blank · 23 comment · 23 complexity · 40fa32590716d4182f1ee21034d5f467 MD5 · raw file

  1. package org.ala.rest;
  2. import com.vividsolutions.jts.geom.Geometry;
  3. import java.io.IOException;
  4. import java.io.StringWriter;
  5. import java.text.DecimalFormat;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import org.geotools.data.DataStore;
  11. import java.util.Map;
  12. import java.util.logging.Logger;
  13. import javax.servlet.ServletContext;
  14. import org.geoserver.catalog.Catalog;
  15. import org.geoserver.catalog.LayerInfo;
  16. import org.geotools.data.FeatureSource;
  17. import org.geotools.feature.FeatureIterator;
  18. import org.opengis.feature.Feature;
  19. import org.geoserver.config.GeoServer;
  20. import org.geoserver.platform.GeoServerExtensions;
  21. import org.geotools.filter.text.cql2.CQL;
  22. import org.opengis.feature.Property;
  23. import org.vfny.geoserver.util.DataStoreUtils;
  24. import org.geoserver.wfs.response.GeoJSONBuilder;
  25. import org.geotools.util.logging.Logging;
  26. import org.opengis.feature.type.GeometryType;
  27. import org.opengis.geometry.BoundingBox;
  28. /**
  29. *
  30. *@author angus
  31. */
  32. public class GazetteerFeature {
  33. private static final Logger logger = Logging.getLogger("org.ala.rest.GazetteerFeature");
  34. String id;
  35. String name;
  36. Map advanced_properties; //detailed feature metadata
  37. Map<String,String> properties; //basic feature metadata (to displayed in UI)
  38. List<String> geometries = new ArrayList<String>();
  39. /**
  40. * Instantiates a gazetteer feature given an id string and layer name
  41. * @param layerName
  42. * @param idAttribute1
  43. * @throws IOException
  44. * @throws Exception
  45. */
  46. public GazetteerFeature(String layerName, String idAttribute1) throws IOException, Exception {
  47. logger.finer("param: layerName: " + layerName);
  48. logger.finer("param: idAttribute1: " + idAttribute1);
  49. GazetteerConfig gc = new GazetteerConfig();
  50. GeoServer gs = GeoServerExtensions.bean(GeoServer.class);
  51. ServletContext sc = GeoServerExtensions.bean(ServletContext.class);
  52. Catalog catalog = gs.getCatalog();
  53. //check to see if layer exists, if not check to see if alias exists ...
  54. if (!gc.layerNameExists(layerName)) {
  55. logger.finer("layer " + layerName + " does not exist - trying aliases.");
  56. layerName = gc.getNameFromAlias(layerName);
  57. if (layerName.compareTo("") == 0) {
  58. logger.finer("no aliases found for layer, giving up");
  59. return;
  60. }
  61. }
  62. //Use search to find matches (provides case insensitive matching)
  63. String[] layers = {layerName};
  64. String searchTerms = idAttribute1;
  65. Search search = new Search(searchTerms, layers, "id");
  66. ArrayList<SearchResultItem> results = search.getResults();
  67. if (results.size() == 0) {
  68. logger.severe("No results returned - this isn't great");
  69. throw new Exception("No results returned - this isn't great");
  70. }
  71. logger.finer("Number of hits is " + results.size());
  72. SearchResultItem searchResultItem = results.get(0);
  73. //grab the first result (highest hit)
  74. logger.finer("Match idAttribute1: " + searchResultItem.idAttribute1);
  75. idAttribute1 = searchResultItem.idAttribute1;
  76. LayerInfo layerInfo = catalog.getLayerByName(layerName);
  77. Map params = layerInfo.getResource().getStore().getConnectionParameters();
  78. DataStore dataStore = DataStoreUtils.acquireDataStore(params, sc);
  79. try {
  80. if (dataStore == null) {
  81. throw new Exception("Could not find datastore for this layer");
  82. } else {
  83. FeatureSource layer = dataStore.getFeatureSource(layerName);
  84. String cql = gc.getIdAttribute1Name(layerName) + "='" + idAttribute1.replace('_', ' ') + "'";
  85. logger.finer("cql: " + cql);
  86. FeatureIterator features = layer.getFeatures(CQL.toFilter(cql)).features();
  87. try {
  88. if (features.hasNext()) {
  89. while (features.hasNext()) {
  90. Feature feature = (Feature) features.next();
  91. String layerAlias = "";
  92. layerAlias = gc.getLayerAlias(layerName);
  93. if (layerAlias.compareTo("") == 0){
  94. layerAlias = layerName;
  95. }
  96. logger.finer("Layer Alias is : " + layerAlias);
  97. this.id = layerAlias + "/" + feature.getProperty(gc.getIdAttribute1Name(layerName)).getValue().toString().replace(" ", "_");
  98. logger.info("Feature ID is : " + this.id);
  99. this.properties = new HashMap<String,String>();
  100. this.properties.put("Feature_ID", this.id);
  101. this.name = feature.getProperty(gc.getNameAttributeName(layerName)).getValue().toString();
  102. logger.info("Feature Name is : " + this.name);
  103. this.properties.put("Feature_Name", this.name);
  104. //Construct a geoJSON representation of the geometry using GeoJSONBuilder
  105. //logger.info("Feature geom is " + feature.getDefaultGeometryProperty().getValue().toString());
  106. StringWriter w = new StringWriter();
  107. GeoJSONBuilder geoJson = new GeoJSONBuilder(w);
  108. geoJson.writeGeom((Geometry) feature.getDefaultGeometryProperty().getValue());
  109. BoundingBox bb = feature.getBounds();
  110. Double minx = new Double(bb.getMinX());
  111. Double miny = new Double(bb.getMinY());
  112. Double maxx = new Double(bb.getMaxX());
  113. Double maxy = new Double(bb.getMaxY());
  114. if (maxx.compareTo(minx) == 0 && maxy.compareTo(miny) == 0){
  115. String point = "(" + strRoundDouble(miny) + "," + strRoundDouble(minx) + ")";
  116. this.properties.put("Point", point);
  117. logger.finer("Point is: " + point);
  118. }
  119. else{
  120. String boundingBox = "((" + strRoundDouble(miny) + "," + strRoundDouble(minx) + "),(" + strRoundDouble(maxy) + "," + strRoundDouble(maxx) + "))";
  121. this.properties.put("Bounding_Box", boundingBox);
  122. logger.finer("Bounding box is: " + boundingBox);
  123. }
  124. //Get Metadata link from config
  125. this.properties.put("Layer_Metadata", gc.getMetadataPath(layerName));
  126. logger.finer("Layer metadata url is " + gc.getBaseURL() + "/layers/" + layerName);
  127. this.geometries.add(w.toString());
  128. //Add all the feature properties to the geojson properties object
  129. Collection<Property> featureProperties = feature.getProperties();
  130. String geomName = feature.getDefaultGeometryProperty().getName().toString();
  131. this.advanced_properties = new HashMap();
  132. for (Property property : featureProperties) {
  133. if ((property.getName() != null) && (property.getValue() != null) && (!(property.getName().toString().contentEquals(geomName)))) {
  134. this.properties.put(property.getName().toString(), property.getValue().toString());
  135. }
  136. }
  137. }
  138. } else {
  139. throw new Exception("Could not find feature");
  140. }
  141. } finally {
  142. features.close();
  143. }
  144. }
  145. } finally {
  146. dataStore.dispose();
  147. }
  148. }
  149. public Map getJSONMap() {
  150. Map<String, Object> map = new HashMap<String, Object>();
  151. map.put("type", "GeometryCollection");
  152. map.put("id", this.id);
  153. map.put("name", this.name);
  154. map.put("properties", this.properties);
  155. map.put("geometries", this.geometries);
  156. return map;
  157. }
  158. /**
  159. * Returns a string representation of a Double to four decimal places
  160. * @param inValue
  161. * @return
  162. */
  163. public String strRoundDouble(Double inValue){
  164. DecimalFormat fourDec = new DecimalFormat("0.0000");
  165. fourDec.setGroupingUsed(false);
  166. return fourDec.format(inValue.doubleValue());
  167. }
  168. }