Omaha #4354: Modify Damage Path tool so each polygon has its own properties, demo bug fixes.
Change-Id: Ib69c19fa518f5e89638af1eba391ee6954f7891d Former-commit-id: affaf23ed435cd3dc62e074cf19a8c4c478d7295
This commit is contained in:
parent
372f7b5362
commit
744b5c3c5b
12 changed files with 320 additions and 120 deletions
|
@ -3,12 +3,6 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<extension
|
<extension
|
||||||
point="com.raytheon.viz.ui.contextualMenu">
|
point="com.raytheon.viz.ui.contextualMenu">
|
||||||
<contextualMenu
|
|
||||||
actionClass="com.raytheon.uf.viz.damagepath.OpenGeoJsonPropertiesDlgAction"
|
|
||||||
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
|
|
||||||
name="Set Properties"
|
|
||||||
sortID="3">
|
|
||||||
</contextualMenu>
|
|
||||||
<contextualMenu
|
<contextualMenu
|
||||||
actionClass="com.raytheon.uf.viz.damagepath.ImportFromDistanceSpeedAction"
|
actionClass="com.raytheon.uf.viz.damagepath.ImportFromDistanceSpeedAction"
|
||||||
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
|
capabilityClass="com.raytheon.uf.viz.damagepath.DamagePathLayer"
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -32,6 +31,9 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
import org.eclipse.core.runtime.IStatus;
|
import org.eclipse.core.runtime.IStatus;
|
||||||
import org.eclipse.core.runtime.Status;
|
import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.core.runtime.jobs.Job;
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
import org.eclipse.jface.action.IMenuManager;
|
||||||
|
import org.geotools.data.DataUtilities;
|
||||||
|
import org.geotools.data.simple.SimpleFeatureCollection;
|
||||||
import org.geotools.feature.simple.SimpleFeatureBuilder;
|
import org.geotools.feature.simple.SimpleFeatureBuilder;
|
||||||
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
|
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
|
||||||
import org.opengis.feature.simple.SimpleFeature;
|
import org.opengis.feature.simple.SimpleFeature;
|
||||||
|
@ -49,15 +51,16 @@ import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType;
|
||||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||||
import com.raytheon.uf.common.localization.LocalizationFileOutputStream;
|
import com.raytheon.uf.common.localization.LocalizationFileOutputStream;
|
||||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||||
|
import com.raytheon.uf.common.util.Pair;
|
||||||
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
import com.raytheon.uf.viz.core.IGraphicsTarget;
|
||||||
import com.raytheon.uf.viz.core.exception.VizException;
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
import com.raytheon.uf.viz.core.rsc.LoadProperties;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||||
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
|
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
|
||||||
import com.raytheon.uf.viz.drawing.polygon.PolygonLayer;
|
import com.raytheon.uf.viz.drawing.polygon.PolygonLayer;
|
||||||
import com.raytheon.uf.viz.drawing.polygon.PolygonUtil;
|
import com.raytheon.uf.viz.drawing.polygon.PolygonUtil;
|
||||||
import com.vividsolutions.jts.geom.Coordinate;
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
import com.vividsolutions.jts.geom.GeometryCollection;
|
|
||||||
import com.vividsolutions.jts.geom.Polygon;
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,6 +81,8 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
* Jun 08, 2015 4355 dgilling Fix NullPointerException in loadJob.
|
* Jun 08, 2015 4355 dgilling Fix NullPointerException in loadJob.
|
||||||
* Jun 12, 2015 4375 dgilling Fix ConcurrentModificationException in
|
* Jun 12, 2015 4375 dgilling Fix ConcurrentModificationException in
|
||||||
* initInternal.
|
* initInternal.
|
||||||
|
* Jun 18, 2015 4354 dgilling Allow each polygon to have their own
|
||||||
|
* properties.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -111,8 +116,6 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||||
|
|
||||||
private static final String PATH = DIR + IPathManager.SEPARATOR + FILE;
|
private static final String PATH = DIR + IPathManager.SEPARATOR + FILE;
|
||||||
|
|
||||||
private Map<String, String> featureProperties = Collections.emptyMap();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JVM property to specify the localization level to attempt to save/load
|
* JVM property to specify the localization level to attempt to save/load
|
||||||
* with. Falls back to USER if not defined.
|
* with. Falls back to USER if not defined.
|
||||||
|
@ -171,7 +174,7 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||||
private void setDefaultPolygon() {
|
private void setDefaultPolygon() {
|
||||||
Polygon polygon = PolygonUtil.makeDefaultPolygon(getResourceContainer()
|
Polygon polygon = PolygonUtil.makeDefaultPolygon(getResourceContainer()
|
||||||
.getActiveDisplayPane().getRenderableDisplay());
|
.getActiveDisplayPane().getRenderableDisplay());
|
||||||
DrawablePolygon drawablePolygon = new DrawablePolygon(polygon, this);
|
DrawablePolygon drawablePolygon = new DamagePathPolygon(polygon, this);
|
||||||
polygons.add(0, drawablePolygon);
|
polygons.add(0, drawablePolygon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,18 +253,24 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||||
protected void loadDamagePath(LocalizationFile file) {
|
protected void loadDamagePath(LocalizationFile file) {
|
||||||
try {
|
try {
|
||||||
DamagePathLoader loader = new DamagePathLoader(file);
|
DamagePathLoader loader = new DamagePathLoader(file);
|
||||||
Collection<Polygon> newPolygons = loader.getPolygons();
|
Collection<Pair<Polygon, Map<String, String>>> newData = loader
|
||||||
if (!newPolygons.isEmpty()) {
|
.getDamagePathData();
|
||||||
|
if (!newData.isEmpty()) {
|
||||||
|
Collection<DrawablePolygon> newDamagePaths = new ArrayList<>(
|
||||||
|
newData.size());
|
||||||
|
for (Pair<Polygon, Map<String, String>> data : newData) {
|
||||||
|
newDamagePaths.add(new DamagePathPolygon(data.getFirst(),
|
||||||
|
data.getSecond(), this));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* specifically call super.resetPolygon() cause
|
* specifically call super.resetPolygon() cause
|
||||||
* this.resetPolygon() will save the file and we don't want to
|
* this.resetPolygon() will save the file and we don't want to
|
||||||
* do that or we could infinite loop of load, save, load,
|
* do that or we could infinite loop of load, save, load,
|
||||||
* save...
|
* save...
|
||||||
*/
|
*/
|
||||||
super.resetPolygons(newPolygons);
|
super.resetPolygons(newDamagePaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
featureProperties = loader.getProperties();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler.error(
|
statusHandler.error(
|
||||||
"Error loading damage path file " + file.getName(), e);
|
"Error loading damage path file " + file.getName(), e);
|
||||||
|
@ -273,8 +282,8 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||||
try {
|
try {
|
||||||
fos = file.openOutputStream();
|
fos = file.openOutputStream();
|
||||||
IGeoJsonService json = new SimpleGeoJsonService();
|
IGeoJsonService json = new SimpleGeoJsonService();
|
||||||
SimpleFeature feature = buildFeature();
|
SimpleFeatureCollection featureCollection = buildFeatureCollection();
|
||||||
json.serialize(feature, fos);
|
json.serialize(featureCollection, fos);
|
||||||
fos.closeAndSave();
|
fos.closeAndSave();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
if (fos != null) {
|
if (fos != null) {
|
||||||
|
@ -289,18 +298,16 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleFeature buildFeature() {
|
private SimpleFeature buildFeature(final DamagePathPolygon damagePath) {
|
||||||
Map<String, String> jsonProps = getFeatureProperties();
|
Map<String, String> jsonProps = damagePath.getProperties();
|
||||||
|
|
||||||
String id = jsonProps.get(GeoJsonMapUtil.ID_KEY);
|
String id = jsonProps.get(GeoJsonMapUtil.ID_KEY);
|
||||||
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
|
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
|
||||||
typeBuilder.setName("feature");
|
typeBuilder.setName("feature");
|
||||||
|
|
||||||
Collection<Polygon> polygons = getPolygons();
|
Geometry polygon = damagePath.getPolygon();
|
||||||
GeometryCollection geomCollection = PolygonUtil.FACTORY
|
|
||||||
.createGeometryCollection(polygons.toArray(new Geometry[0]));
|
|
||||||
typeBuilder.setDefaultGeometry("the_geom");
|
typeBuilder.setDefaultGeometry("the_geom");
|
||||||
typeBuilder.add("the_geom", geomCollection.getClass());
|
typeBuilder.add("the_geom", polygon.getClass());
|
||||||
|
|
||||||
Collection<String> keysToIgnore = Arrays.asList(GeoJsonMapUtil.ID_KEY);
|
Collection<String> keysToIgnore = Arrays.asList(GeoJsonMapUtil.ID_KEY);
|
||||||
Set<String> keySet = jsonProps.keySet();
|
Set<String> keySet = jsonProps.keySet();
|
||||||
|
@ -315,25 +322,25 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||||
|
|
||||||
SimpleFeatureType type = typeBuilder.buildFeatureType();
|
SimpleFeatureType type = typeBuilder.buildFeatureType();
|
||||||
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
|
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(type);
|
||||||
if (geomCollection != null) {
|
if (polygon != null) {
|
||||||
featureBuilder.add(geomCollection);
|
featureBuilder.add(polygon);
|
||||||
}
|
}
|
||||||
featureBuilder.addAll(values);
|
featureBuilder.addAll(values);
|
||||||
return featureBuilder.buildFeature(id);
|
return featureBuilder.buildFeature(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getFeatureProperties() {
|
public SimpleFeatureCollection buildFeatureCollection() {
|
||||||
return featureProperties;
|
List<SimpleFeature> features = new ArrayList<>(polygons.size());
|
||||||
}
|
for (DrawablePolygon polygon : polygons) {
|
||||||
|
features.add(buildFeature((DamagePathPolygon) polygon));
|
||||||
|
}
|
||||||
|
|
||||||
public void setFeatureProperties(Map<String, String> featureProperties) {
|
return DataUtilities.collection(features);
|
||||||
this.featureProperties = featureProperties;
|
|
||||||
saveJob.schedule();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPolygon(Coordinate[] coords) {
|
public void addPolygon(Coordinate[] coords) {
|
||||||
super.addPolygon(coords);
|
super.addPolygon(new DamagePathPolygon(coords, this));
|
||||||
saveJob.schedule();
|
saveJob.schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,4 +349,28 @@ public class DamagePathLayer<T extends DamagePathResourceData> extends
|
||||||
super.deletePolygon(index);
|
super.deletePolygon(index);
|
||||||
saveJob.schedule();
|
saveJob.schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addContextMenuItems(IMenuManager menuManager, int x, int y) {
|
||||||
|
if (!getCapability(EditableCapability.class).isEditable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.addContextMenuItems(menuManager, x, y);
|
||||||
|
|
||||||
|
int onPolygonIdx = uiInput.pointOnPolygon(x, y);
|
||||||
|
if (onPolygonIdx >= 0) {
|
||||||
|
menuManager.add(new OpenGeoJsonPropertiesDlgAction(
|
||||||
|
(DamagePathPolygon) polygons.get(onPolygonIdx)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DrawablePolygon getNewDrawable() {
|
||||||
|
return new DamagePathPolygon(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void scheduleSaveJob() {
|
||||||
|
saveJob.schedule();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,15 @@ import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.geotools.feature.FeatureCollection;
|
||||||
|
import org.geotools.feature.FeatureIterator;
|
||||||
import org.opengis.feature.Property;
|
import org.opengis.feature.Property;
|
||||||
import org.opengis.feature.simple.SimpleFeature;
|
import org.opengis.feature.simple.SimpleFeature;
|
||||||
|
import org.opengis.feature.simple.SimpleFeatureType;
|
||||||
import org.opengis.feature.type.Name;
|
import org.opengis.feature.type.Name;
|
||||||
|
|
||||||
import com.raytheon.uf.common.json.JsonException;
|
import com.raytheon.uf.common.json.JsonException;
|
||||||
|
@ -40,6 +44,7 @@ import com.raytheon.uf.common.json.geo.IGeoJsonService;
|
||||||
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
|
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
|
||||||
import com.raytheon.uf.common.localization.LocalizationFile;
|
import com.raytheon.uf.common.localization.LocalizationFile;
|
||||||
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
import com.raytheon.uf.common.localization.exception.LocalizationException;
|
||||||
|
import com.raytheon.uf.common.util.Pair;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
import com.vividsolutions.jts.geom.Geometry;
|
||||||
import com.vividsolutions.jts.geom.Polygon;
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
import com.vividsolutions.jts.operation.valid.IsValidOp;
|
import com.vividsolutions.jts.operation.valid.IsValidOp;
|
||||||
|
@ -55,6 +60,8 @@ import com.vividsolutions.jts.operation.valid.IsValidOp;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jun 05, 2015 #4375 dgilling Initial creation
|
* Jun 05, 2015 #4375 dgilling Initial creation
|
||||||
|
* Jun 18, 2015 #4354 dgilling Support FeatureCollections so each polygon
|
||||||
|
* can have its own properties.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -70,9 +77,7 @@ public final class DamagePathLoader {
|
||||||
|
|
||||||
private static final String INVALID_POLYGON = "Damage path file contains an invalid Polyon at index %d: %s";
|
private static final String INVALID_POLYGON = "Damage path file contains an invalid Polyon at index %d: %s";
|
||||||
|
|
||||||
private final Collection<Polygon> polygons;
|
private final Collection<Pair<Polygon, Map<String, String>>> damagePathData;
|
||||||
|
|
||||||
private final Map<String, String> properties;
|
|
||||||
|
|
||||||
public DamagePathLoader(LocalizationFile locFile)
|
public DamagePathLoader(LocalizationFile locFile)
|
||||||
throws LocalizationException, IOException, JsonException {
|
throws LocalizationException, IOException, JsonException {
|
||||||
|
@ -86,8 +91,7 @@ public final class DamagePathLoader {
|
||||||
|
|
||||||
private DamagePathLoader(LocalizationFile locFileSource, Path realFileSource)
|
private DamagePathLoader(LocalizationFile locFileSource, Path realFileSource)
|
||||||
throws LocalizationException, IOException, JsonException {
|
throws LocalizationException, IOException, JsonException {
|
||||||
this.polygons = new ArrayList<>();
|
this.damagePathData = new ArrayList<>();
|
||||||
this.properties = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
if (locFileSource != null) {
|
if (locFileSource != null) {
|
||||||
loadFromLocalizationFile(locFileSource);
|
loadFromLocalizationFile(locFileSource);
|
||||||
|
@ -96,12 +100,8 @@ public final class DamagePathLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<Polygon> getPolygons() {
|
public Collection<Pair<Polygon, Map<String, String>>> getDamagePathData() {
|
||||||
return polygons;
|
return damagePathData;
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getProperties() {
|
|
||||||
return properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadFromLocalizationFile(final LocalizationFile locFile)
|
private void loadFromLocalizationFile(final LocalizationFile locFile)
|
||||||
|
@ -120,29 +120,36 @@ public final class DamagePathLoader {
|
||||||
|
|
||||||
private void loadFromInputStream(final InputStream is) throws JsonException {
|
private void loadFromInputStream(final InputStream is) throws JsonException {
|
||||||
Geometry deserializedGeom = null;
|
Geometry deserializedGeom = null;
|
||||||
|
Map<String, String> deserializedProps = Collections.emptyMap();
|
||||||
GeoJsonMapUtil geoJsonUtil = new GeoJsonMapUtil();
|
GeoJsonMapUtil geoJsonUtil = new GeoJsonMapUtil();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For compatibility with any users that may have an autosaved damage
|
* For compatibility with any users that may have an autosaved damage
|
||||||
* path file from build 15.1, we'll support deserializing both Geometry
|
* path file from previous builds, we'll support deserializing Geometry,
|
||||||
* and Feature GeoJSON types.
|
* Feature and FeatureCollection GeoJSON types.
|
||||||
*
|
*
|
||||||
* TODO: remove this code for code that just expects the file to always
|
* TODO: remove this code for code that just expects the file to always
|
||||||
* be a Feature.
|
* be a FeatureCollection.
|
||||||
*/
|
*/
|
||||||
Map<String, Object> jsonObject = (Map<String, Object>) new BasicJsonService()
|
Map<String, Object> jsonObject = (Map<String, Object>) new BasicJsonService()
|
||||||
.deserialize(is, LinkedHashMap.class);
|
.deserialize(is, LinkedHashMap.class);
|
||||||
String geoJsonType = jsonObject.get(GeoJsonMapUtil.TYPE_KEY).toString();
|
String geoJsonType = jsonObject.get(GeoJsonMapUtil.TYPE_KEY).toString();
|
||||||
if (geoJsonType.equals(GeoJsonMapUtil.FEATURE_TYPE)) {
|
if (geoJsonType.equals(GeoJsonMapUtil.FEATURE_COLL_TYPE)) {
|
||||||
|
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = geoJsonUtil
|
||||||
|
.populateFeatureCollection(jsonObject);
|
||||||
|
populateDataFromFeatureCollection(featureCollection);
|
||||||
|
return;
|
||||||
|
} else if (geoJsonType.equals(GeoJsonMapUtil.FEATURE_TYPE)) {
|
||||||
SimpleFeature feature = geoJsonUtil.populateFeature(jsonObject);
|
SimpleFeature feature = geoJsonUtil.populateFeature(jsonObject);
|
||||||
deserializedGeom = (Geometry) feature.getDefaultGeometry();
|
deserializedGeom = (Geometry) feature.getDefaultGeometry();
|
||||||
|
|
||||||
Name defaultGeomAttrib = feature.getDefaultGeometryProperty()
|
Name defaultGeomAttrib = feature.getDefaultGeometryProperty()
|
||||||
.getName();
|
.getName();
|
||||||
properties.put(GeoJsonMapUtil.ID_KEY, feature.getID());
|
deserializedProps = new LinkedHashMap<>();
|
||||||
|
deserializedProps.put(GeoJsonMapUtil.ID_KEY, feature.getID());
|
||||||
for (Property p : feature.getProperties()) {
|
for (Property p : feature.getProperties()) {
|
||||||
if (!defaultGeomAttrib.equals(p.getName())) {
|
if (!defaultGeomAttrib.equals(p.getName())) {
|
||||||
properties.put(p.getName().toString(), p.getValue()
|
deserializedProps.put(p.getName().toString(), p.getValue()
|
||||||
.toString());
|
.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +167,9 @@ public final class DamagePathLoader {
|
||||||
Polygon newPolygon = (Polygon) geomN;
|
Polygon newPolygon = (Polygon) geomN;
|
||||||
IsValidOp validator = new IsValidOp(newPolygon);
|
IsValidOp validator = new IsValidOp(newPolygon);
|
||||||
if (validator.isValid()) {
|
if (validator.isValid()) {
|
||||||
polygons.add(newPolygon);
|
Pair<Polygon, Map<String, String>> polygonAndProps = new Pair<>(
|
||||||
|
newPolygon, deserializedProps);
|
||||||
|
damagePathData.add(polygonAndProps);
|
||||||
} else {
|
} else {
|
||||||
throw new JsonException(String.format(INVALID_POLYGON, i,
|
throw new JsonException(String.format(INVALID_POLYGON, i,
|
||||||
validator.getValidationError()));
|
validator.getValidationError()));
|
||||||
|
@ -190,32 +199,49 @@ public final class DamagePathLoader {
|
||||||
private void loadFromInputStreamFuture(final InputStream is)
|
private void loadFromInputStreamFuture(final InputStream is)
|
||||||
throws JsonException {
|
throws JsonException {
|
||||||
IGeoJsonService json = new SimpleGeoJsonService();
|
IGeoJsonService json = new SimpleGeoJsonService();
|
||||||
SimpleFeature feature = json.deserializeFeature(is);
|
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection = json
|
||||||
Geometry featureGeom = (Geometry) feature.getDefaultGeometry();
|
.deserializeFeatureCollection(is);
|
||||||
|
populateDataFromFeatureCollection(featureCollection);
|
||||||
|
}
|
||||||
|
|
||||||
int numGeometries = featureGeom.getNumGeometries();
|
private void populateDataFromFeatureCollection(
|
||||||
for (int i = 0; i < numGeometries; i++) {
|
FeatureCollection<SimpleFeatureType, SimpleFeature> featureCollection)
|
||||||
Geometry geomN = featureGeom.getGeometryN(i);
|
throws JsonException {
|
||||||
if (geomN instanceof Polygon) {
|
try (FeatureIterator<SimpleFeature> iter = featureCollection.features()) {
|
||||||
Polygon newPolygon = (Polygon) geomN;
|
int featureIdx = 0;
|
||||||
IsValidOp validator = new IsValidOp(newPolygon);
|
while (iter.hasNext()) {
|
||||||
if (validator.isValid()) {
|
SimpleFeature feature = iter.next();
|
||||||
polygons.add(newPolygon);
|
|
||||||
|
Geometry geom = (Geometry) feature.getDefaultGeometry();
|
||||||
|
if (geom instanceof Polygon) {
|
||||||
|
Polygon newPolygon = (Polygon) geom;
|
||||||
|
IsValidOp validator = new IsValidOp(newPolygon);
|
||||||
|
if (!validator.isValid()) {
|
||||||
|
throw new JsonException(String.format(INVALID_POLYGON,
|
||||||
|
featureIdx, validator.getValidationError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> properties = new LinkedHashMap<>();
|
||||||
|
Name defaultGeomAttrib = feature
|
||||||
|
.getDefaultGeometryProperty().getName();
|
||||||
|
properties.put(GeoJsonMapUtil.ID_KEY, feature.getID());
|
||||||
|
for (Property p : feature.getProperties()) {
|
||||||
|
if (!defaultGeomAttrib.equals(p.getName())) {
|
||||||
|
properties.put(p.getName().toString(), p.getValue()
|
||||||
|
.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<Polygon, Map<String, String>> polygonAndProps = new Pair<>(
|
||||||
|
newPolygon, properties);
|
||||||
|
damagePathData.add(polygonAndProps);
|
||||||
} else {
|
} else {
|
||||||
throw new JsonException(String.format(INVALID_POLYGON, i,
|
throw new JsonException(String.format(
|
||||||
validator.getValidationError()));
|
UNSUPPORTED_GEOM_TYPE, geom.getGeometryType(),
|
||||||
|
featureIdx));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new JsonException(String.format(UNSUPPORTED_GEOM_TYPE,
|
|
||||||
geomN.getGeometryType(), i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Name defaultGeomAttrib = feature.getDefaultGeometryProperty().getName();
|
featureIdx++;
|
||||||
properties.put(GeoJsonMapUtil.ID_KEY, feature.getID());
|
|
||||||
for (Property p : feature.getProperties()) {
|
|
||||||
if (!defaultGeomAttrib.equals(p.getName())) {
|
|
||||||
properties.put(p.getName().toString(), p.getValue().toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.damagepath;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
|
||||||
|
import com.raytheon.uf.viz.drawing.polygon.PolygonLayer;
|
||||||
|
import com.vividsolutions.jts.geom.Coordinate;
|
||||||
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of {@code DrawablePolygon} to support GeoJSON properties.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jun 18, 2015 #4354 dgilling Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author dgilling
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DamagePathPolygon extends DrawablePolygon {
|
||||||
|
|
||||||
|
private static final Map<String, String> DEFAULT_PROPS = Collections
|
||||||
|
.emptyMap();
|
||||||
|
|
||||||
|
private Map<String, String> properties;
|
||||||
|
|
||||||
|
public DamagePathPolygon(PolygonLayer<?> polygonLayer) {
|
||||||
|
super(polygonLayer);
|
||||||
|
this.properties = DEFAULT_PROPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DamagePathPolygon(Polygon polygon, PolygonLayer<?> polygonLayer) {
|
||||||
|
this(polygon, DEFAULT_PROPS, polygonLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DamagePathPolygon(Polygon polygon, Map<String, String> properties,
|
||||||
|
PolygonLayer<?> polygonLayer) {
|
||||||
|
super(polygon, polygonLayer);
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DamagePathPolygon(Coordinate[] coords, PolygonLayer<?> polygonLayer) {
|
||||||
|
super(coords, polygonLayer);
|
||||||
|
this.properties = DEFAULT_PROPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetPolygon(DrawablePolygon newPolygon) {
|
||||||
|
super.resetPolygon(newPolygon);
|
||||||
|
|
||||||
|
if (newPolygon instanceof DamagePathPolygon) {
|
||||||
|
DamagePathPolygon newDamagePath = (DamagePathPolygon) newPolygon;
|
||||||
|
properties = newDamagePath.getProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getProperties() {
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperties(Map<String, String> properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ import org.eclipse.jface.dialogs.MessageDialog;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.FileDialog;
|
import org.eclipse.swt.widgets.FileDialog;
|
||||||
import org.eclipse.swt.widgets.Shell;
|
import org.eclipse.swt.widgets.Shell;
|
||||||
import org.opengis.feature.simple.SimpleFeature;
|
import org.geotools.data.simple.SimpleFeatureCollection;
|
||||||
|
|
||||||
import com.raytheon.uf.common.json.geo.IGeoJsonService;
|
import com.raytheon.uf.common.json.geo.IGeoJsonService;
|
||||||
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
|
import com.raytheon.uf.common.json.geo.SimpleGeoJsonService;
|
||||||
|
@ -34,7 +34,6 @@ import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.viz.core.VizApp;
|
import com.raytheon.uf.viz.core.VizApp;
|
||||||
import com.raytheon.viz.ui.VizWorkbenchManager;
|
import com.raytheon.viz.ui.VizWorkbenchManager;
|
||||||
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||||
import com.vividsolutions.jts.geom.Geometry;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action to export a damage path as GeoJSON to a file specified by the user.
|
* Action to export a damage path as GeoJSON to a file specified by the user.
|
||||||
|
@ -50,6 +49,8 @@ import com.vividsolutions.jts.geom.Geometry;
|
||||||
* Jun 05, 2015 4375 dgilling Prompt user before exporting feature
|
* Jun 05, 2015 4375 dgilling Prompt user before exporting feature
|
||||||
* with no polygons.
|
* with no polygons.
|
||||||
* Jun 09, 2015 4355 dgilling Rename action for UI.
|
* Jun 09, 2015 4355 dgilling Rename action for UI.
|
||||||
|
* Jun 18, 2015 #4354 dgilling Support FeatureCollections so each
|
||||||
|
* polygon can have its own properties.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -85,11 +86,10 @@ public class ExportDamagePathAction extends AbstractRightClickAction {
|
||||||
|
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
||||||
SimpleFeature feature = layer.buildFeature();
|
SimpleFeatureCollection featureCollection = layer
|
||||||
|
.buildFeatureCollection();
|
||||||
|
|
||||||
Geometry defaultGeometry = (Geometry) feature
|
if (featureCollection.size() < 1) {
|
||||||
.getDefaultGeometry();
|
|
||||||
if (defaultGeometry.getNumGeometries() < 1) {
|
|
||||||
boolean export = MessageDialog.openConfirm(shell,
|
boolean export = MessageDialog.openConfirm(shell,
|
||||||
CONFIRM_DLG_TITLE, CONFIRM_DLG_MSG);
|
CONFIRM_DLG_TITLE, CONFIRM_DLG_MSG);
|
||||||
if (!export) {
|
if (!export) {
|
||||||
|
@ -101,7 +101,7 @@ public class ExportDamagePathAction extends AbstractRightClickAction {
|
||||||
|
|
||||||
try (FileOutputStream fos = new FileOutputStream(filename)) {
|
try (FileOutputStream fos = new FileOutputStream(filename)) {
|
||||||
IGeoJsonService json = new SimpleGeoJsonService();
|
IGeoJsonService json = new SimpleGeoJsonService();
|
||||||
json.serialize(feature, fos);
|
json.serialize(featureCollection, fos);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
statusHandler.error(
|
statusHandler.error(
|
||||||
"Error exporting damage path file to "
|
"Error exporting damage path file to "
|
||||||
|
|
|
@ -22,7 +22,7 @@ package com.raytheon.uf.viz.damagepath;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.opengis.feature.simple.SimpleFeature;
|
import org.geotools.data.simple.SimpleFeatureCollection;
|
||||||
|
|
||||||
import com.raytheon.uf.common.damagepath.request.ExportToLdadRequest;
|
import com.raytheon.uf.common.damagepath.request.ExportToLdadRequest;
|
||||||
import com.raytheon.uf.common.json.JsonException;
|
import com.raytheon.uf.common.json.JsonException;
|
||||||
|
@ -46,6 +46,8 @@ import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Jun 08, 2015 #4355 dgilling Initial creation
|
* Jun 08, 2015 #4355 dgilling Initial creation
|
||||||
|
* Jun 18, 2015 #4354 dgilling Support FeatureCollections so each
|
||||||
|
* polygon can have its own properties.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -69,9 +71,10 @@ public class ExportToLdadAction extends AbstractRightClickAction {
|
||||||
|
|
||||||
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
|
try (ByteArrayOutputStream outStream = new ByteArrayOutputStream()) {
|
||||||
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
||||||
SimpleFeature feature = layer.buildFeature();
|
SimpleFeatureCollection featureCollection = layer
|
||||||
|
.buildFeatureCollection();
|
||||||
|
|
||||||
new SimpleGeoJsonService().serialize(feature, outStream);
|
new SimpleGeoJsonService().serialize(featureCollection, outStream);
|
||||||
jsonData = outStream.toByteArray();
|
jsonData = outStream.toByteArray();
|
||||||
} catch (JsonException | IOException e) {
|
} catch (JsonException | IOException e) {
|
||||||
statusHandler.error(
|
statusHandler.error(
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
**/
|
**/
|
||||||
package com.raytheon.uf.viz.damagepath;
|
package com.raytheon.uf.viz.damagepath;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.widgets.FileDialog;
|
import org.eclipse.swt.widgets.FileDialog;
|
||||||
|
@ -28,7 +30,11 @@ import org.eclipse.swt.widgets.Shell;
|
||||||
import com.raytheon.uf.common.json.JsonException;
|
import com.raytheon.uf.common.json.JsonException;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.util.Pair;
|
||||||
import com.raytheon.uf.viz.core.VizApp;
|
import com.raytheon.uf.viz.core.VizApp;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||||
|
import com.raytheon.uf.viz.drawing.polygon.DrawablePolygon;
|
||||||
import com.raytheon.viz.ui.VizWorkbenchManager;
|
import com.raytheon.viz.ui.VizWorkbenchManager;
|
||||||
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||||
import com.vividsolutions.jts.geom.Polygon;
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
@ -47,6 +53,8 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
* Apr 23, 2015 4354 dgilling Support GeoJSON Feature objects.
|
* Apr 23, 2015 4354 dgilling Support GeoJSON Feature objects.
|
||||||
* Jun 03, 2015 4375 dgilling Support multiple polygons.
|
* Jun 03, 2015 4375 dgilling Support multiple polygons.
|
||||||
* Jun 09, 2015 4355 dgilling Rename action for UI.
|
* Jun 09, 2015 4355 dgilling Rename action for UI.
|
||||||
|
* Jun 18, 2015 4354 dgilling Support modifications to loader so each
|
||||||
|
* polygon can have its own properties.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -80,10 +88,16 @@ public class ImportDamagePathAction extends AbstractRightClickAction {
|
||||||
try {
|
try {
|
||||||
DamagePathLoader loader = new DamagePathLoader(filename);
|
DamagePathLoader loader = new DamagePathLoader(filename);
|
||||||
|
|
||||||
Collection<Polygon> newPolygons = loader.getPolygons();
|
Collection<Pair<Polygon, Map<String, String>>> newData = loader
|
||||||
if (!newPolygons.isEmpty()) {
|
.getDamagePathData();
|
||||||
layer.resetPolygons(newPolygons);
|
if (!newData.isEmpty()) {
|
||||||
layer.setFeatureProperties(loader.getProperties());
|
Collection<DrawablePolygon> newDamagePaths = new ArrayList<>(
|
||||||
|
newData.size());
|
||||||
|
for (Pair<Polygon, Map<String, String>> data : newData) {
|
||||||
|
newDamagePaths.add(new DamagePathPolygon(data
|
||||||
|
.getFirst(), data.getSecond(), layer));
|
||||||
|
}
|
||||||
|
layer.resetPolygons(newDamagePaths);
|
||||||
} else {
|
} else {
|
||||||
throw new JsonException(
|
throw new JsonException(
|
||||||
"Damage path file contains no polygons.");
|
"Damage path file contains no polygons.");
|
||||||
|
@ -96,4 +110,10 @@ public class ImportDamagePathAction extends AbstractRightClickAction {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
AbstractVizResource<?, ?> layer = getSelectedRsc();
|
||||||
|
return layer.getCapability(EditableCapability.class).isEditable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import com.raytheon.uf.viz.core.VizApp;
|
||||||
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
import com.raytheon.uf.viz.core.drawables.ResourcePair;
|
||||||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||||
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
import com.raytheon.uf.viz.core.rsc.ResourceList;
|
||||||
|
import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability;
|
||||||
import com.raytheon.viz.awipstools.ui.layer.DistanceSpeedLayer;
|
import com.raytheon.viz.awipstools.ui.layer.DistanceSpeedLayer;
|
||||||
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
import com.raytheon.viz.ui.cmenu.AbstractRightClickAction;
|
||||||
import com.vividsolutions.jts.geom.Polygon;
|
import com.vividsolutions.jts.geom.Polygon;
|
||||||
|
@ -41,6 +42,8 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
* Mar 23, 2015 3977 nabowle Initial creation
|
* Mar 23, 2015 3977 nabowle Initial creation
|
||||||
* Jun 01, 2015 3975 dgilling Update for DamageLayer changes for
|
* Jun 01, 2015 3975 dgilling Update for DamageLayer changes for
|
||||||
* multiple polygon support.
|
* multiple polygon support.
|
||||||
|
* Jun 18, 2015 4354 dgilling Update isEnabled to consider editable
|
||||||
|
* capability.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -85,9 +88,10 @@ public class ImportFromDistanceSpeedAction extends AbstractRightClickAction {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
boolean enabled = super.isEnabled();
|
AbstractVizResource<?, ?> rsc = getSelectedRsc();
|
||||||
|
boolean enabled = rsc.getCapability(EditableCapability.class)
|
||||||
|
.isEditable();
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
AbstractVizResource<?, ?> rsc = getSelectedRsc();
|
|
||||||
if (rsc != null) {
|
if (rsc != null) {
|
||||||
enabled = findImportLayer(rsc) != null;
|
enabled = findImportLayer(rsc) != null;
|
||||||
}
|
}
|
||||||
|
@ -111,5 +115,4 @@ public class ImportFromDistanceSpeedAction extends AbstractRightClickAction {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Apr 23, 2015 #4354 dgilling Initial creation
|
* Apr 23, 2015 #4354 dgilling Initial creation
|
||||||
* Jun 09, 2015 #4355 dgilling Rename action for UI.
|
* Jun 09, 2015 #4355 dgilling Rename action for UI.
|
||||||
|
* Jun 18, 2015 #4354 dgilling Allow individual properties object for
|
||||||
|
* each polygon.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -48,8 +50,11 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
||||||
|
|
||||||
public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction {
|
public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction {
|
||||||
|
|
||||||
public OpenGeoJsonPropertiesDlgAction() {
|
private final DamagePathPolygon damagePath;
|
||||||
|
|
||||||
|
public OpenGeoJsonPropertiesDlgAction(final DamagePathPolygon damagePath) {
|
||||||
super("Set Properties...");
|
super("Set Properties...");
|
||||||
|
this.damagePath = damagePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,10 +64,10 @@ public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction {
|
||||||
public void run() {
|
public void run() {
|
||||||
Shell shell = VizWorkbenchManager.getInstance()
|
Shell shell = VizWorkbenchManager.getInstance()
|
||||||
.getCurrentWindow().getShell();
|
.getCurrentWindow().getShell();
|
||||||
final DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
|
||||||
final Map<String, String> geoJsonProps = layer
|
|
||||||
.getFeatureProperties();
|
|
||||||
|
|
||||||
|
final DamagePathLayer<?> layer = (DamagePathLayer<?>) getSelectedRsc();
|
||||||
|
final Map<String, String> geoJsonProps = damagePath
|
||||||
|
.getProperties();
|
||||||
EditGeoJsonPropertiesDlg dlg = new EditGeoJsonPropertiesDlg(
|
EditGeoJsonPropertiesDlg dlg = new EditGeoJsonPropertiesDlg(
|
||||||
shell, geoJsonProps);
|
shell, geoJsonProps);
|
||||||
dlg.setCloseCallback(new ICloseCallback() {
|
dlg.setCloseCallback(new ICloseCallback() {
|
||||||
|
@ -72,7 +77,8 @@ public class OpenGeoJsonPropertiesDlgAction extends AbstractRightClickAction {
|
||||||
if ((returnValue != null)
|
if ((returnValue != null)
|
||||||
&& (!geoJsonProps.equals(returnValue))) {
|
&& (!geoJsonProps.equals(returnValue))) {
|
||||||
Map<String, String> updatedProperties = (Map<String, String>) returnValue;
|
Map<String, String> updatedProperties = (Map<String, String>) returnValue;
|
||||||
layer.setFeatureProperties(updatedProperties);
|
damagePath.setProperties(updatedProperties);
|
||||||
|
layer.scheduleSaveJob();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,6 +50,7 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* May 27, 2015 #4375 dgilling Initial creation
|
* May 27, 2015 #4375 dgilling Initial creation
|
||||||
|
* Jun 18, 2015 #4354 dgilling Correct behavior of project.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -168,6 +169,23 @@ public class DrawablePolygon implements IRenderable2 {
|
||||||
if (coords != null && coords.length > 0) {
|
if (coords != null && coords.length > 0) {
|
||||||
polygon = PolygonUtil.FACTORY.createPolygon(coords);
|
polygon = PolygonUtil.FACTORY.createPolygon(coords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetPolygon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetPolygon(DrawablePolygon newPolygon) {
|
||||||
|
synchronized (lock) {
|
||||||
|
if ((newPolygon != null) && (newPolygon.getPolygon() != null)) {
|
||||||
|
polygon = newPolygon.getPolygon();
|
||||||
|
}
|
||||||
|
|
||||||
|
resetPolygon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetPolygon() {
|
||||||
|
synchronized (lock) {
|
||||||
if (wireframeShape != null) {
|
if (wireframeShape != null) {
|
||||||
wireframeShape.reset();
|
wireframeShape.reset();
|
||||||
}
|
}
|
||||||
|
@ -193,7 +211,7 @@ public class DrawablePolygon implements IRenderable2 {
|
||||||
public void project(CoordinateReferenceSystem crs) {
|
public void project(CoordinateReferenceSystem crs) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
dispose();
|
dispose();
|
||||||
polygon = null;
|
resetPolygon();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ import com.vividsolutions.jts.geom.util.AffineTransformation;
|
||||||
* Mar 04, 2015 4194 njensen Block other input on middle click drag on edges
|
* Mar 04, 2015 4194 njensen Block other input on middle click drag on edges
|
||||||
* Jun 03, 2015 4375 dgilling Add methods for adding/deleting polygons,
|
* Jun 03, 2015 4375 dgilling Add methods for adding/deleting polygons,
|
||||||
* support multiple polygons in PolygonLayer.
|
* support multiple polygons in PolygonLayer.
|
||||||
|
* Jun 18, 2015 4354 dgilling Changed visibility of pointOnPolygon.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -306,7 +307,7 @@ public class PolygonInputAdapter extends RscInputAdapter<PolygonLayer<?>> {
|
||||||
* @return Index of the polygon this screen point is on or -1 if it is not
|
* @return Index of the polygon this screen point is on or -1 if it is not
|
||||||
* on any polygons.
|
* on any polygons.
|
||||||
*/
|
*/
|
||||||
protected int pointOnPolygon(int screenX, int screenY) {
|
public int pointOnPolygon(int screenX, int screenY) {
|
||||||
int polygonIdx = -1;
|
int polygonIdx = -1;
|
||||||
Coordinate worldCoord = screenToLatLon(screenX, screenY);
|
Coordinate worldCoord = screenToLatLon(screenX, screenY);
|
||||||
if (worldCoord != null) {
|
if (worldCoord != null) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ package com.raytheon.uf.viz.drawing.polygon;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.jface.action.IMenuManager;
|
import org.eclipse.jface.action.IMenuManager;
|
||||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||||
|
@ -59,6 +58,9 @@ import com.vividsolutions.jts.geom.Polygon;
|
||||||
* May 15, 2015 4375 dgilling Support multiple polygons.
|
* May 15, 2015 4375 dgilling Support multiple polygons.
|
||||||
* Jun 12, 2015 4375 dgilling Only show AddVertexAction when on polygon's
|
* Jun 12, 2015 4375 dgilling Only show AddVertexAction when on polygon's
|
||||||
* edge and not near a current vertex.
|
* edge and not near a current vertex.
|
||||||
|
* Jun 17, 2015 4354 dgilling Fix bugs that would clear polygons on
|
||||||
|
* capability change or reproject.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
@ -75,7 +77,7 @@ public class PolygonLayer<T extends AbstractResourceData> extends
|
||||||
|
|
||||||
protected PolygonInputAdapter uiInput = new PolygonInputAdapter(this);
|
protected PolygonInputAdapter uiInput = new PolygonInputAdapter(this);
|
||||||
|
|
||||||
protected final List<DrawablePolygon> polygons;
|
protected final LinkedList<DrawablePolygon> polygons;
|
||||||
|
|
||||||
public PolygonLayer(T resourceData, LoadProperties loadProperties) {
|
public PolygonLayer(T resourceData, LoadProperties loadProperties) {
|
||||||
super(resourceData, loadProperties);
|
super(resourceData, loadProperties);
|
||||||
|
@ -128,7 +130,7 @@ public class PolygonLayer<T extends AbstractResourceData> extends
|
||||||
if ((index < polygons.size()) && (coords != null && coords.length > 0)) {
|
if ((index < polygons.size()) && (coords != null && coords.length > 0)) {
|
||||||
DrawablePolygon polygon = polygons.remove(index);
|
DrawablePolygon polygon = polygons.remove(index);
|
||||||
polygon.resetPolygon(coords);
|
polygon.resetPolygon(coords);
|
||||||
polygons.add(0, polygon);
|
polygons.push(polygon);
|
||||||
issueRefresh();
|
issueRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,7 +138,12 @@ public class PolygonLayer<T extends AbstractResourceData> extends
|
||||||
@Override
|
@Override
|
||||||
protected void resourceDataChanged(ChangeType type, Object updateObject) {
|
protected void resourceDataChanged(ChangeType type, Object updateObject) {
|
||||||
if (type.equals(ChangeType.CAPABILITY)) {
|
if (type.equals(ChangeType.CAPABILITY)) {
|
||||||
clearPolygons();
|
if (polygons != null) {
|
||||||
|
for (DrawablePolygon polygon : polygons) {
|
||||||
|
polygon.resetPolygon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
issueRefresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,6 +152,7 @@ public class PolygonLayer<T extends AbstractResourceData> extends
|
||||||
for (DrawablePolygon drawPolygon : polygons) {
|
for (DrawablePolygon drawPolygon : polygons) {
|
||||||
drawPolygon.project(crs);
|
drawPolygon.project(crs);
|
||||||
}
|
}
|
||||||
|
issueRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Polygon getPolygon(int index) {
|
public Polygon getPolygon(int index) {
|
||||||
|
@ -155,24 +163,13 @@ public class PolygonLayer<T extends AbstractResourceData> extends
|
||||||
resetPolygon(index, polygon.getExteriorRing().getCoordinates());
|
resetPolygon(index, polygon.getExteriorRing().getCoordinates());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void clearPolygons() {
|
public void resetPolygons(Collection<DrawablePolygon> newPolygons) {
|
||||||
if (polygons != null) {
|
|
||||||
for (DrawablePolygon polygon : polygons) {
|
|
||||||
polygon.dispose();
|
|
||||||
}
|
|
||||||
polygons.clear();
|
|
||||||
issueRefresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resetPolygons(Collection<Polygon> newPolygons) {
|
|
||||||
if ((polygons != null) && (!newPolygons.isEmpty())) {
|
if ((polygons != null) && (!newPolygons.isEmpty())) {
|
||||||
resizePolygonStack(newPolygons.size());
|
resizePolygonStack(newPolygons.size());
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Polygon newPolygon : newPolygons) {
|
for (DrawablePolygon newPolygon : newPolygons) {
|
||||||
polygons.get(i).resetPolygon(
|
polygons.get(i).resetPolygon(newPolygon);
|
||||||
newPolygon.getExteriorRing().getCoordinates());
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,21 +182,27 @@ public class PolygonLayer<T extends AbstractResourceData> extends
|
||||||
if (newSize > currentSize) {
|
if (newSize > currentSize) {
|
||||||
int toAdd = newSize - currentSize;
|
int toAdd = newSize - currentSize;
|
||||||
for (int i = 0; i < toAdd; i++) {
|
for (int i = 0; i < toAdd; i++) {
|
||||||
polygons.add(new DrawablePolygon(this));
|
polygons.add(getNewDrawable());
|
||||||
}
|
}
|
||||||
} else if (currentSize > newSize) {
|
} else if (currentSize > newSize) {
|
||||||
int toDelete = currentSize - newSize;
|
int toDelete = currentSize - newSize;
|
||||||
for (int i = 0; i < toDelete; i++) {
|
for (int i = 0; i < toDelete; i++) {
|
||||||
DrawablePolygon polygonToDelete = polygons.remove(polygons
|
DrawablePolygon polygonToDelete = polygons.removeLast();
|
||||||
.size() - 1);
|
|
||||||
polygonToDelete.dispose();
|
polygonToDelete.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected DrawablePolygon getNewDrawable() {
|
||||||
|
return new DrawablePolygon(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void addPolygon(Coordinate[] coords) {
|
public void addPolygon(Coordinate[] coords) {
|
||||||
DrawablePolygon polygon = new DrawablePolygon(coords, this);
|
addPolygon(new DrawablePolygon(coords, this));
|
||||||
polygons.add(0, polygon);
|
}
|
||||||
|
|
||||||
|
protected void addPolygon(DrawablePolygon newPolygon) {
|
||||||
|
polygons.push(newPolygon);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deletePolygon(int index) {
|
public void deletePolygon(int index) {
|
||||||
|
@ -224,6 +227,10 @@ public class PolygonLayer<T extends AbstractResourceData> extends
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void addContextMenuItems(IMenuManager menuManager, int x, int y) {
|
public void addContextMenuItems(IMenuManager menuManager, int x, int y) {
|
||||||
|
if (!getCapability(EditableCapability.class).isEditable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int edgePolygonIdx = uiInput.pointOnEdge(x, y);
|
int edgePolygonIdx = uiInput.pointOnEdge(x, y);
|
||||||
boolean onEdge = (edgePolygonIdx >= 0);
|
boolean onEdge = (edgePolygonIdx >= 0);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue