public Resolution split() throws JSONException { JSONObject json = new JSONObject(); json.put("success", Boolean.FALSE); String error = null; if (appLayer == null) { error = "Invalid parameters"; } else if (unauthorized) { error = "Not authorized"; } else { FeatureSource fs = null; try { if (this.splitFeatureFID == null) { throw new IllegalArgumentException("Split feature ID is null"); } if (this.toSplitWithFeature == null) { throw new IllegalArgumentException("Split line is null"); } fs = this.layer.getFeatureType().openGeoToolsFeatureSource(); if (!(fs instanceof SimpleFeatureStore)) { throw new IllegalArgumentException("Feature source does not support editing"); } this.store = (SimpleFeatureStore) fs; List<FeatureId> ids = this.splitFeature(); if (ids.size() < 2) { throw new IllegalArgumentException("Split failed, check that geometries overlap"); } json.put("fids", ids); json.put("success", Boolean.TRUE); } catch (IllegalArgumentException e) { log.warn("Split error", e); error = e.getLocalizedMessage(); } catch (Exception e) { log.error(String.format("Exception splitting feature %s", this.splitFeatureFID), e); error = e.toString(); if (e.getCause() != null) { error += "; cause: " + e.getCause().toString(); } } finally { if (fs != null) { fs.getDataStore().dispose(); } } } if (error != null) { json.put("error", error); } return new StreamingResolution("application/json", new StringReader(json.toString())); }
@Test @Ignore // this test is skipped, it checks something that formally is what we should expect, // but for the moment this breaks big time the shapefile renderer optimizations // until we get rid of the latter let's be a little lax on this one... public void testFeatureSource() throws Exception { File file = copyShapefiles("shapes/archsites.shp"); tempDir = file.getParentFile(); DataStore dds = new DirectoryDataStore(tempDir, getFileStoreFactory()); FeatureSource fs = dds.getFeatureSource("archsites"); assertNotNull(fs); assertSame(dds, fs.getDataStore()); dds.dispose(); }
/** * Get the features as JSONArray with the given params * * @param al The application layer(if there is a application layer) * @param ft The featuretype that must be used to get the features * @param fs The featureSource * @param q The query * @param sort The attribute name that is used to sort * @param dir Sort direction (DESC or ASC) * @return JSONArray with features. * @throws IOException if any * @throws JSONException if transforming to json fails * @throws Exception if any */ public JSONArray getJSONFeatures( ApplicationLayer al, SimpleFeatureType ft, FeatureSource fs, Query q, String sort, String dir) throws IOException, JSONException, Exception { Map<String, String> attributeAliases = new HashMap<String, String>(); if (!edit) { for (AttributeDescriptor ad : ft.getAttributes()) { if (ad.getAlias() != null) { attributeAliases.put(ad.getName(), ad.getAlias()); } } } List<String> propertyNames; if (al != null) { propertyNames = this.setPropertyNames(al, q, ft, edit); } else { propertyNames = new ArrayList<String>(); for (AttributeDescriptor ad : ft.getAttributes()) { propertyNames.add(ad.getName()); } } if (sort != null) { setSortBy(q, propertyNames, sort, dir); } /* Use the first property as sort field, otherwise geotools while give a error when quering * a JDBC featureType without a primary key. */ else if (fs instanceof org.geotools.jdbc.JDBCFeatureSource && !propertyNames.isEmpty()) { setSortBy(q, propertyNames.get(0), dir); } Integer start = q.getStartIndex(); if (start == null) { start = 0; } boolean offsetSupported = fs.getQueryCapabilities().isOffsetSupported(); // if offSet is not supported, get more features (start + the wanted features) if (!offsetSupported && q.getMaxFeatures() < MAX_FEATURES) { q.setMaxFeatures(q.getMaxFeatures() + start); } FeatureIterator<SimpleFeature> it = null; JSONArray features = new JSONArray(); try { it = fs.getFeatures(q).features(); int featureIndex = 0; while (it.hasNext()) { SimpleFeature feature = it.next(); /* if offset not supported and there are more features returned then * only get the features after index >= start*/ if (offsetSupported || featureIndex >= start) { JSONObject j = this.toJSONFeature( new JSONObject(), feature, ft, al, propertyNames, attributeAliases, 0); features.put(j); } featureIndex++; } } finally { if (it != null) { it.close(); } fs.getDataStore().dispose(); } return features; }
/** Populate the json object with related featues */ private JSONObject populateWithRelatedFeatures( JSONObject j, SimpleFeature feature, SimpleFeatureType ft, ApplicationLayer al, int index) throws Exception { if (ft.hasRelations()) { JSONArray related_featuretypes = new JSONArray(); for (FeatureTypeRelation rel : ft.getRelations()) { boolean isJoin = rel.getType().equals(FeatureTypeRelation.JOIN); if (isJoin) { FeatureSource foreignFs = rel.getForeignFeatureType().openGeoToolsFeatureSource(TIMEOUT); FeatureIterator<SimpleFeature> foreignIt = null; try { Query foreignQ = new Query(foreignFs.getName().toString()); // create filter Filter filter = createFilter(feature, rel); if (filter == null) { continue; } // if join only get 1 feature foreignQ.setMaxFeatures(1); foreignQ.setFilter(filter); // set propertynames List<String> propertyNames; if (al != null) { propertyNames = setPropertyNames(al, foreignQ, rel.getForeignFeatureType(), edit); } else { propertyNames = new ArrayList<String>(); for (AttributeDescriptor ad : rel.getForeignFeatureType().getAttributes()) { propertyNames.add(ad.getName()); } } if (propertyNames.isEmpty()) { // if there are no properties to retrieve just get out continue; } // get aliases Map<String, String> attributeAliases = new HashMap<String, String>(); if (!edit) { for (AttributeDescriptor ad : rel.getForeignFeatureType().getAttributes()) { if (ad.getAlias() != null) { attributeAliases.put(ad.getName(), ad.getAlias()); } } } // Get Feature and populate JSON object with the values. foreignIt = foreignFs.getFeatures(foreignQ).features(); while (foreignIt.hasNext()) { SimpleFeature foreignFeature = foreignIt.next(); // join it in the same json j = toJSONFeature( j, foreignFeature, rel.getForeignFeatureType(), al, propertyNames, attributeAliases, index); } } finally { if (foreignIt != null) { foreignIt.close(); } foreignFs.getDataStore().dispose(); } } else { Filter filter = createFilter(feature, rel); if (filter == null) { continue; } JSONObject related_ft = new JSONObject(); related_ft.put("filter", CQL.toCQL(filter)); related_ft.put("id", rel.getForeignFeatureType().getId()); related_ft.put("foreignFeatureTypeName", rel.getForeignFeatureType().getTypeName()); related_featuretypes.put(related_ft); } } if (related_featuretypes.length() > 0) { j.put("related_featuretypes", related_featuretypes); } } return j; }