mirror of
https://github.com/meteoinfo/MeteoInfo.git
synced 2025-12-08 20:36:05 +00:00
support output GeoJSON file from Layer
This commit is contained in:
parent
cac71057b7
commit
b02bda02f5
@ -33,7 +33,8 @@ public class PointD implements Cloneable{
|
||||
}
|
||||
|
||||
/**
|
||||
* Contructor
|
||||
* Constructor
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
@ -46,6 +47,22 @@ public class PointD implements Cloneable{
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
|
||||
/**
|
||||
* To double array
|
||||
* @return Double array
|
||||
*/
|
||||
public double[] toArray() {
|
||||
return new double[]{X, Y};
|
||||
}
|
||||
|
||||
/**
|
||||
* To float array
|
||||
* @return Float array
|
||||
*/
|
||||
public float[] toFloatArray() {
|
||||
return new float[]{(float) X, (float) Y};
|
||||
}
|
||||
|
||||
/**
|
||||
* Equals of two pointDs
|
||||
* @param p PointD
|
||||
|
||||
@ -137,6 +137,15 @@ public class ColorUtil {
|
||||
// </editor-fold>
|
||||
// <editor-fold desc="Methods">
|
||||
|
||||
/**
|
||||
* Convert color r,g,b to hex string
|
||||
* @param color The color
|
||||
* @return Hex string
|
||||
*/
|
||||
public static String toHex(Color color) {
|
||||
return String.format("#%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a color to hex string
|
||||
*
|
||||
|
||||
@ -67,7 +67,7 @@ import java.util.zip.ZipInputStream;
|
||||
public static String getVersion(){
|
||||
String version = GlobalUtil.class.getPackage().getImplementationVersion();
|
||||
if (version == null || version.equals("")) {
|
||||
version = "3.7.8";
|
||||
version = "3.7.9";
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
package org.meteoinfo.geo.io;
|
||||
|
||||
import org.meteoinfo.common.colors.ColorUtil;
|
||||
import org.meteoinfo.geo.layer.VectorLayer;
|
||||
import org.meteoinfo.geometry.io.geojson.*;
|
||||
import org.meteoinfo.geometry.legend.ColorBreak;
|
||||
import org.meteoinfo.geometry.legend.LegendScheme;
|
||||
import org.meteoinfo.geometry.legend.LegendType;
|
||||
import org.meteoinfo.geometry.legend.PolygonBreak;
|
||||
import org.meteoinfo.geometry.shape.Shape;
|
||||
import org.meteoinfo.geometry.shape.ShapeTypes;
|
||||
import org.meteoinfo.ndarray.DataType;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Map;
|
||||
|
||||
public class GeoJSONReader {
|
||||
|
||||
/**
|
||||
* Create a VectorLayer from GeoJSON feature collection
|
||||
* @param features The feature collection
|
||||
* @return VectorLayer object
|
||||
*/
|
||||
public static VectorLayer read(FeatureCollection features) {
|
||||
Shape shape = GeoJSONUtil.toShape(features.getFeature(0).getGeometry());
|
||||
VectorLayer layer = new VectorLayer(shape.getShapeType());
|
||||
String fieldName = "title";
|
||||
layer.editAddField(fieldName, DataType.STRING);
|
||||
LegendScheme ls = new LegendScheme(shape.getShapeType());
|
||||
ls.setLegendType(LegendType.UNIQUE_VALUE);
|
||||
ls.setFieldName(fieldName);
|
||||
for (int i = 0; i < features.getNumFeatures(); i++) {
|
||||
Feature feature = features.getFeature(i);
|
||||
Map<String, Object> properties = feature.getProperties();
|
||||
String titleValue = (String) properties.get("title");
|
||||
PolygonBreak cb = new PolygonBreak();
|
||||
cb.setStartValue(titleValue);
|
||||
cb.setCaption(titleValue);
|
||||
Color color = ColorUtil.parseToColor((String) properties.get("fill"));
|
||||
float alpha = Float.parseFloat(properties.get("fill-opacity").toString());
|
||||
color = ColorUtil.getColor(color, alpha);
|
||||
cb.setColor(color);
|
||||
color = ColorUtil.parseToColor((String) properties.get("stroke"));
|
||||
alpha = Float.parseFloat(properties.get("stroke-opacity").toString());
|
||||
color = ColorUtil.getColor(color, alpha);
|
||||
cb.setOutlineColor(color);
|
||||
float lineWidth = Float.parseFloat(properties.get("stroke-width").toString());
|
||||
cb.setOutlineSize(lineWidth);
|
||||
ls.addLegendBreak(cb);
|
||||
Geometry geometry = feature.getGeometry();
|
||||
if (geometry != null) {
|
||||
try {
|
||||
int idx = layer.getShapeNum();
|
||||
layer.editInsertShape(GeoJSONUtil.toShape(geometry), idx);
|
||||
layer.editCellValue(fieldName, idx, titleValue);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
layer.setLegendScheme(ls);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a VectorLayer from GeoJSON string
|
||||
* @param json The GeoJSON string
|
||||
* @return VectorLayer object
|
||||
*/
|
||||
public static VectorLayer read(String json) {
|
||||
FeatureCollection features = (FeatureCollection) GeoJSONFactory.create(json);
|
||||
|
||||
return read(features);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package org.meteoinfo.geo.io;
|
||||
|
||||
import org.meteoinfo.common.colors.ColorUtil;
|
||||
import org.meteoinfo.geo.layer.VectorLayer;
|
||||
import org.meteoinfo.geometry.io.geojson.Feature;
|
||||
import org.meteoinfo.geometry.io.geojson.FeatureCollection;
|
||||
import org.meteoinfo.geometry.io.geojson.GeoJSONUtil;
|
||||
import org.meteoinfo.geometry.io.geojson.Geometry;
|
||||
import org.meteoinfo.geometry.legend.*;
|
||||
import org.meteoinfo.geometry.shape.Shape;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class GeoJSONWriter {
|
||||
|
||||
/**
|
||||
* Write a vector layer to GeoJSON feature collection
|
||||
*
|
||||
* @param layer The vector layer
|
||||
* @return GeoJSON feature collection
|
||||
*/
|
||||
public static FeatureCollection write(VectorLayer layer) {
|
||||
Feature[] features = new Feature[layer.getShapeNum()];
|
||||
LegendScheme ls = layer.getLegendScheme();
|
||||
for (int i = 0; i < layer.getShapeNum(); i++) {
|
||||
Shape shape = layer.getShape(i);
|
||||
Geometry geometry = GeoJSONUtil.fromShape(shape);
|
||||
Map<String, Object> properties = new HashMap<>();
|
||||
ColorBreak cb = ls.getLegendBreak(shape.getLegendIndex());
|
||||
switch (cb.getBreakType()) {
|
||||
case POINT_BREAK:
|
||||
PointBreak pointBreak = (PointBreak) cb;
|
||||
properties.put("marker-size", "medium");
|
||||
properties.put("marker-color", ColorUtil.toHex(pointBreak.getColor()));
|
||||
break;
|
||||
case POLYLINE_BREAK:
|
||||
PolylineBreak polylineBreak = (PolylineBreak) cb;
|
||||
properties.put("stroke", ColorUtil.toHex(polylineBreak.getColor()));
|
||||
properties.put("stroke-opacity", polylineBreak.getColor().getAlpha() / 255.f);
|
||||
properties.put("stroke-width", polylineBreak.getWidth());
|
||||
break;
|
||||
case POLYGON_BREAK:
|
||||
PolygonBreak polygonBreak = (PolygonBreak) cb;
|
||||
properties.put("fill", ColorUtil.toHex(cb.getColor()));
|
||||
properties.put("fill-opacity", cb.getColor().getAlpha() / 255.f);
|
||||
if (polygonBreak.isDrawOutline()) {
|
||||
properties.put("stroke", ColorUtil.toHex(polygonBreak.getOutlineColor()));
|
||||
properties.put("stroke-opacity", polygonBreak.getOutlineColor().getAlpha() / 255.f);
|
||||
properties.put("stroke-width", polygonBreak.getOutlineSize());
|
||||
} else {
|
||||
properties.put("stroke-opacity", 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
properties.put("title", cb.getCaption());
|
||||
features[i] = new Feature(geometry, properties);
|
||||
}
|
||||
|
||||
return new FeatureCollection(features);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1412,6 +1412,17 @@ public class VectorLayer extends MapLayer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit: Remove a shape by index
|
||||
* @param idx The index
|
||||
*/
|
||||
public void editRemoveShape(int idx) {
|
||||
if (idx >= 0 && idx < this.getShapeNum() - 1) {
|
||||
this._shapeList.remove(idx);
|
||||
this._attributeTable.getTable().removeRow(idx);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLayerExtent(Shape aShape) {
|
||||
if (this.getShapeNum() == 1) {
|
||||
this.setExtent((Extent) aShape.getExtent().clone());
|
||||
|
||||
@ -37,6 +37,16 @@
|
||||
<artifactId>jts-core</artifactId>
|
||||
<version>1.19.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.13.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>2.13.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonPropertyOrder({"type", "id", "geometry", "properties"})
|
||||
public class Feature extends GeoJSON {
|
||||
@JsonInclude(Include.NON_EMPTY)
|
||||
private final Object id;
|
||||
private final Geometry geometry;
|
||||
private final Map<String, Object> properties;
|
||||
|
||||
public Feature(
|
||||
@JsonProperty("geometry") Geometry geometry,
|
||||
@JsonProperty("properties") Map<String,Object> properties) {
|
||||
this(null, geometry, properties);
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public Feature(
|
||||
@JsonProperty("id") Object id,
|
||||
@JsonProperty("geometry") Geometry geometry,
|
||||
@JsonProperty("properties") Map<String,Object> properties) {
|
||||
super();
|
||||
this.id = id;
|
||||
this.geometry = geometry;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public Object getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Geometry getGeometry() {
|
||||
return geometry;
|
||||
}
|
||||
|
||||
public Map<String, Object> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
@JsonPropertyOrder({"type", "features"})
|
||||
public class FeatureCollection extends GeoJSON {
|
||||
private final Feature[] features;
|
||||
|
||||
@JsonCreator
|
||||
public FeatureCollection(@JsonProperty("features") Feature[] features) {
|
||||
super();
|
||||
this.features = features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get features
|
||||
* @return Features
|
||||
*/
|
||||
public Feature[] getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of features
|
||||
* @return Number of features
|
||||
*/
|
||||
public int getNumFeatures() {
|
||||
return features.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a feature by index
|
||||
* @param index The index
|
||||
* @return The feature
|
||||
*/
|
||||
public Feature getFeature(int index) {
|
||||
return features[index];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.core.JsonGenerationException;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@JsonTypeInfo(
|
||||
use = JsonTypeInfo.Id.NAME,
|
||||
include = JsonTypeInfo.As.EXISTING_PROPERTY,
|
||||
property = "type"
|
||||
)
|
||||
@JsonSubTypes( {
|
||||
@JsonSubTypes.Type(value=Point.class, name="Point" ),
|
||||
@JsonSubTypes.Type(value=LineString.class, name="LineString" ),
|
||||
@JsonSubTypes.Type(value=Polygon.class, name="Polygon" ),
|
||||
@JsonSubTypes.Type(value=MultiPoint.class, name="MultiPoint" ),
|
||||
@JsonSubTypes.Type(value=MultiLineString.class, name="MultiLineString" ),
|
||||
@JsonSubTypes.Type(value=MultiPolygon.class, name="MultiPolygon" ),
|
||||
@JsonSubTypes.Type(value=Feature.class, name="Feature" ),
|
||||
@JsonSubTypes.Type(value=FeatureCollection.class, name="FeatureCollection" ),
|
||||
@JsonSubTypes.Type(value=GeometryCollection.class, name="GeometryCollection" )
|
||||
})
|
||||
public abstract class GeoJSON {
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@JsonProperty("type")
|
||||
private String type;
|
||||
|
||||
@JsonCreator
|
||||
public GeoJSON() {
|
||||
setType(getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
try {
|
||||
return mapper.writeValueAsString(this);
|
||||
} catch (JsonGenerationException e) {
|
||||
return "Unhandled exception occured when serializing this instance";
|
||||
} catch (JsonMappingException e) {
|
||||
return "Unhandled exception occured when serializing this instance";
|
||||
} catch (IOException e) {
|
||||
return "Unhandled exception occured when serializing this instance";
|
||||
}
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParseException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.type.MapType;
|
||||
|
||||
public class GeoJSONFactory {
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public static GeoJSON create(String json) {
|
||||
try {
|
||||
JsonNode node = mapper.readTree(json);
|
||||
String type = node.get("type").asText();
|
||||
if (type.equals("FeatureCollection"))
|
||||
return readFeatureCollection(node);
|
||||
else if (type.equals("Feature"))
|
||||
return readFeature(node);
|
||||
else
|
||||
return readGeometry(node, type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static FeatureCollection readFeatureCollection(JsonNode node)
|
||||
throws JsonParseException, JsonMappingException, IOException, ClassNotFoundException {
|
||||
Iterator<JsonNode> it = node.get("features").iterator();
|
||||
List<Feature> features = new ArrayList<>();
|
||||
while (it.hasNext())
|
||||
features.add(readFeature(it.next()));
|
||||
return new FeatureCollection(features.toArray(new Feature[features.size()]));
|
||||
}
|
||||
|
||||
private static Feature readFeature(JsonNode node)
|
||||
throws JsonParseException, JsonMappingException, IOException, ClassNotFoundException {
|
||||
JsonNode geometryNode = node.get("geometry");
|
||||
MapType javaType = mapper.getTypeFactory().constructMapType(Map.class, String.class, Object.class);
|
||||
JsonNode id = node.get("id");
|
||||
Map<String, Object> properties = mapper.readValue(node.get("properties").traverse(), javaType);
|
||||
Geometry geometry = readGeometry(geometryNode);
|
||||
return new Feature(id, geometry, properties);
|
||||
}
|
||||
|
||||
private static Geometry readGeometry(JsonNode node)
|
||||
throws JsonParseException, JsonMappingException, IOException, ClassNotFoundException {
|
||||
if (node != null && !node.isNull())
|
||||
return readGeometry(node, node.get("type").asText());
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Geometry readGeometry(JsonNode node, String type)
|
||||
throws JsonParseException, JsonMappingException, IOException, ClassNotFoundException {
|
||||
return (Geometry) mapper.readValue(node.traverse(), Class.forName("org.meteoinfo.geometry.io.geojson." + type));
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,341 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import org.meteoinfo.common.PointD;
|
||||
import org.meteoinfo.geometry.shape.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class GeoJSONUtil {
|
||||
|
||||
/**
|
||||
* Convert GeoJSON geometry to shape
|
||||
*
|
||||
* @param geometry The geometry
|
||||
* @return Shape
|
||||
*/
|
||||
public static Shape toShape(Geometry geometry) {
|
||||
if (geometry instanceof Point) {
|
||||
return toShape((Point) geometry);
|
||||
} else if (geometry instanceof LineString) {
|
||||
return toShape((LineString) geometry);
|
||||
} else if (geometry instanceof MultiLineString) {
|
||||
return toShape((MultiLineString) geometry);
|
||||
} else if (geometry instanceof Polygon) {
|
||||
return toShape((Polygon) geometry);
|
||||
} else if (geometry instanceof MultiPolygon) {
|
||||
return toShape((MultiPolygon) geometry);
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert shape to GeoJSON geometry
|
||||
*
|
||||
* @param shape The shape
|
||||
* @return Geometry
|
||||
*/
|
||||
public static Geometry fromShape(Shape shape) {
|
||||
if (shape instanceof PointShape) {
|
||||
return fromShape((PointShape) shape);
|
||||
} else if (shape instanceof PolylineShape) {
|
||||
return fromShape((PolylineShape) shape);
|
||||
} else if (shape instanceof PolygonShape) {
|
||||
return fromShape((PolygonShape) shape);
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert PointShape to GeoJSON Point
|
||||
*
|
||||
* @param pointShape The PointShape object
|
||||
* @return GeoJSON Point object
|
||||
*/
|
||||
public static Point fromShape(PointShape pointShape) {
|
||||
PointD p = pointShape.getPoint();
|
||||
|
||||
return new Point(p.toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GeoJSON Point to PointShape
|
||||
*
|
||||
* @param point The GeoJSON Point object
|
||||
* @return PointShape object
|
||||
*/
|
||||
public static PointShape toShape(Point point) {
|
||||
double[] coordinates = point.getCoordinates();
|
||||
if (coordinates.length == 2) {
|
||||
return new PointShape(new PointD(coordinates[0], coordinates[1]));
|
||||
} else {
|
||||
return new PointZShape(new PointZ(coordinates[0], coordinates[1], coordinates[2]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert PolylineShape to GeoJSON LineString or MultiLineString
|
||||
*
|
||||
* @param polylineShape The PolylineShape object
|
||||
* @return GeoJSON LineString or MultiLineString object
|
||||
*/
|
||||
public static Geometry fromShape(PolylineShape polylineShape) {
|
||||
if (polylineShape.isMultiLine()) {
|
||||
int lineNum = polylineShape.getPartNum();
|
||||
double[][][] coordinates = new double[lineNum][][];
|
||||
int cNum = polylineShape.getShapeType() == ShapeTypes.POLYLINE ? 2 : 3;
|
||||
for (int j = 0; j < lineNum; j++) {
|
||||
Polyline polyline = polylineShape.getPolylines().get(j);
|
||||
int pNum = polyline.getPointList().size();
|
||||
double[][] matrix = new double[pNum][cNum];
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
matrix[i] = polyline.getPointList().get(i).toArray();
|
||||
}
|
||||
coordinates[j] = matrix;
|
||||
}
|
||||
|
||||
return new MultiLineString(coordinates);
|
||||
} else {
|
||||
int cNum = polylineShape.getShapeType() == ShapeTypes.POLYLINE ? 2 : 3;
|
||||
double[][] coordinates = new double[polylineShape.getPointNum()][cNum];
|
||||
for (int i = 0; i < polylineShape.getPointNum(); i++) {
|
||||
coordinates[i] = polylineShape.getPoints().get(i).toArray();
|
||||
}
|
||||
|
||||
return new LineString(coordinates);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GeoJSON LineString to PolylineShape
|
||||
*
|
||||
* @param lineString The GeoJSON LineString object
|
||||
* @return PolylineShape object
|
||||
*/
|
||||
public static PolylineShape toShape(LineString lineString) {
|
||||
double[][] coordinates = lineString.getCoordinates();
|
||||
int pNum = coordinates.length;
|
||||
if (coordinates[0].length == 2) {
|
||||
List<PointD> points = new ArrayList<>();
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointD(coordinates[i][0], coordinates[i][1]));
|
||||
}
|
||||
|
||||
return new PolylineShape(points);
|
||||
} else {
|
||||
List<PointZ> points = new ArrayList<>();
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointZ(coordinates[i][0], coordinates[i][1], coordinates[i][2]));
|
||||
}
|
||||
|
||||
return new PolylineZShape(points);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GeoJSON LineString to PolylineShape
|
||||
*
|
||||
* @param lineString The GeoJSON LineString object
|
||||
* @return PolylineShape object
|
||||
*/
|
||||
public static PolylineShape toShape(MultiLineString lineString) {
|
||||
double[][][] coordinates = lineString.getCoordinates();
|
||||
int lineNum = coordinates.length;
|
||||
int cNum = coordinates[0][0].length;
|
||||
if (cNum == 2) {
|
||||
PolylineShape polylineShape = new PolylineShape();
|
||||
polylineShape.setPartNum(lineNum);
|
||||
polylineShape.parts = new int[lineNum];
|
||||
List<PointD> points = new ArrayList<>();
|
||||
for (int j = 0; j < lineNum; j++) {
|
||||
int pNum = coordinates[j].length;
|
||||
polylineShape.parts[j] = pNum;
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointD(coordinates[j][i][0], coordinates[j][i][1]));
|
||||
}
|
||||
}
|
||||
polylineShape.setPoints(points);
|
||||
|
||||
return polylineShape;
|
||||
} else {
|
||||
PolylineZShape polylineZShape = new PolylineZShape();
|
||||
polylineZShape.setPartNum(lineNum);
|
||||
polylineZShape.parts = new int[lineNum];
|
||||
List<PointZ> points = new ArrayList<>();
|
||||
for (int j = 0; j < lineNum; j++) {
|
||||
int pNum = coordinates[j].length;
|
||||
polylineZShape.parts[j] = pNum;
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointZ(coordinates[j][i][0], coordinates[j][i][1], coordinates[j][i][2]));
|
||||
}
|
||||
}
|
||||
polylineZShape.setPoints(points);
|
||||
|
||||
return polylineZShape;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert PolygonShape to GeoJSON Polygon or MultiPolygon
|
||||
*
|
||||
* @param polygonShape The PolygonShape object
|
||||
* @return GeoJSON Polygon or MultiPolygon object
|
||||
*/
|
||||
public static Geometry fromShape(PolygonShape polygonShape) {
|
||||
int cNum = polygonShape.getShapeType() == ShapeTypes.POLYGON ? 2 : 3;
|
||||
if (polygonShape.isMultiPolygon()) {
|
||||
int polygonNum = polygonShape.getPolygons().size();
|
||||
double[][][][] coordinates = new double[polygonNum][][][];
|
||||
for (int k = 0; k < polygonNum; k++) {
|
||||
org.meteoinfo.geometry.shape.Polygon sPolygon = polygonShape.getPolygon(k);
|
||||
int ringNumber = sPolygon.getRingNumber();
|
||||
double[][][] a3d = new double[ringNumber][][];
|
||||
int pNum = sPolygon.getOutLine().size();
|
||||
double[][] matrix = new double[pNum][cNum];
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
matrix[i] = sPolygon.getOutLine().get(i).toArray();
|
||||
}
|
||||
a3d[0] = matrix;
|
||||
if (sPolygon.hasHole()) {
|
||||
for (int j = 0; j < sPolygon.getHoleLineNumber(); j++) {
|
||||
pNum = sPolygon.getHoleLine(j).size();
|
||||
matrix = new double[pNum][cNum];
|
||||
for (int i = 0; i < sPolygon.getHoleLine(j).size(); i++) {
|
||||
matrix[i] = sPolygon.getHoleLine(j).get(i).toArray();
|
||||
}
|
||||
a3d[j + 1] = matrix;
|
||||
}
|
||||
}
|
||||
coordinates[k] = a3d;
|
||||
}
|
||||
|
||||
return new MultiPolygon(coordinates);
|
||||
} else {
|
||||
org.meteoinfo.geometry.shape.Polygon sPolygon = polygonShape.getPolygon(0);
|
||||
int ringNum = sPolygon.getRingNumber();
|
||||
double[][][] coordinates = new double[ringNum][][];
|
||||
int pNum = sPolygon.getOutLine().size();
|
||||
double[][] matrix = new double[pNum][cNum];
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
matrix[i] = sPolygon.getOutLine().get(i).toArray();
|
||||
}
|
||||
coordinates[0] = matrix;
|
||||
if (sPolygon.hasHole()) {
|
||||
for (int j = 0; j < sPolygon.getHoleLineNumber(); j++) {
|
||||
pNum = sPolygon.getHoleLine(j).size();
|
||||
matrix = new double[pNum][cNum];
|
||||
for (int i = 0; i < sPolygon.getHoleLine(j).size(); i++) {
|
||||
matrix[i] = sPolygon.getHoleLine(j).get(i).toArray();
|
||||
}
|
||||
coordinates[j + 1] = matrix;
|
||||
}
|
||||
}
|
||||
|
||||
return new Polygon(coordinates);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GeoJSON Polygon to PolygonShape
|
||||
*
|
||||
* @param polygon The GeoJSON Polygon object
|
||||
* @return PolygonShape object
|
||||
*/
|
||||
public static PolygonShape toShape(Polygon polygon) {
|
||||
double[][][] coordinates = polygon.getCoordinates();
|
||||
int ringNum = coordinates.length;
|
||||
int cNum = coordinates[0][0].length;
|
||||
if (cNum == 2) {
|
||||
PolygonShape polygonShape = new PolygonShape();
|
||||
polygonShape.setPartNum(ringNum);
|
||||
polygonShape.parts = new int[ringNum];
|
||||
List<PointD> points = new ArrayList<>();
|
||||
for (int j = 0; j < ringNum; j++) {
|
||||
int pNum = coordinates[j].length;
|
||||
polygonShape.parts[j] = pNum;
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointD(coordinates[j][i][0], coordinates[j][i][1]));
|
||||
}
|
||||
}
|
||||
polygonShape.setPoints(points);
|
||||
|
||||
return polygonShape;
|
||||
} else {
|
||||
PolygonZShape polygonZShape = new PolygonZShape();
|
||||
polygonZShape.setPartNum(ringNum);
|
||||
polygonZShape.parts = new int[ringNum];
|
||||
List<PointZ> points = new ArrayList<>();
|
||||
for (int j = 0; j < ringNum; j++) {
|
||||
int pNum = coordinates[j].length;
|
||||
polygonZShape.parts[j] = pNum;
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointZ(coordinates[j][i][0], coordinates[j][i][1], coordinates[j][i][2]));
|
||||
}
|
||||
}
|
||||
polygonZShape.setPoints(points);
|
||||
|
||||
return polygonZShape;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert GeoJSON MultiPolygon to PolygonShape
|
||||
*
|
||||
* @param multiPolygon The GeoJSON MultiPolygon object
|
||||
* @return PolygonShape object
|
||||
*/
|
||||
public static PolygonShape toShape(MultiPolygon multiPolygon) {
|
||||
double[][][][] coordinates = multiPolygon.getCoordinates();
|
||||
int polygonNum = coordinates.length;
|
||||
int cNum = coordinates[0][0][0].length;
|
||||
if (cNum == 2) {
|
||||
List<org.meteoinfo.geometry.shape.Polygon> polygons = new ArrayList<>();
|
||||
for (int k = 0; k < polygonNum; k++) {
|
||||
int ringNum = coordinates[k].length;
|
||||
org.meteoinfo.geometry.shape.Polygon polygon = new org.meteoinfo.geometry.shape.Polygon();
|
||||
for (int j = 0; j < ringNum; j++) {
|
||||
List<PointD> points = new ArrayList<>();
|
||||
int pNum = coordinates[k][j].length;
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointD(coordinates[k][j][i][0], coordinates[k][j][i][1]));
|
||||
}
|
||||
if (j == 0) {
|
||||
polygon.setOutLine(points);
|
||||
} else {
|
||||
polygon.addHole(points);
|
||||
}
|
||||
}
|
||||
polygons.add(polygon);
|
||||
}
|
||||
PolygonShape polygonShape = new PolygonShape();
|
||||
polygonShape.setPolygons(polygons);
|
||||
|
||||
return polygonShape;
|
||||
} else {
|
||||
List<org.meteoinfo.geometry.shape.Polygon> polygons = new ArrayList<>();
|
||||
for (int k = 0; k < polygonNum; k++) {
|
||||
int ringNum = coordinates[k].length;
|
||||
org.meteoinfo.geometry.shape.Polygon polygon = new org.meteoinfo.geometry.shape.Polygon();
|
||||
for (int j = 0; j < ringNum; j++) {
|
||||
List<PointZ> points = new ArrayList<>();
|
||||
int pNum = coordinates[k][j].length;
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
points.add(new PointZ(coordinates[k][j][i][0], coordinates[k][j][i][1],
|
||||
coordinates[k][j][i][2]));
|
||||
}
|
||||
if (j == 0) {
|
||||
polygon.setOutLine(points);
|
||||
} else {
|
||||
polygon.addHole(points);
|
||||
}
|
||||
}
|
||||
polygons.add(polygon);
|
||||
}
|
||||
PolygonZShape polygonZShape = new PolygonZShape();
|
||||
polygonZShape.setPolygons(polygons);
|
||||
|
||||
return polygonZShape;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.fasterxml.jackson.annotation.JsonSubTypes;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonTypeInfo(
|
||||
use = JsonTypeInfo.Id.NAME,
|
||||
include = JsonTypeInfo.As.EXISTING_PROPERTY,
|
||||
property = "type"
|
||||
)
|
||||
@JsonSubTypes( {
|
||||
@JsonSubTypes.Type(value=Point.class, name="Point" ),
|
||||
@JsonSubTypes.Type(value=LineString.class, name="LineString" ),
|
||||
@JsonSubTypes.Type(value=Polygon.class, name="Polygon" ),
|
||||
@JsonSubTypes.Type(value=MultiPoint.class, name="MultiPoint" ),
|
||||
@JsonSubTypes.Type(value=MultiLineString.class, name="MultiLineString" ),
|
||||
@JsonSubTypes.Type(value=MultiPolygon.class, name="MultiPolygon" ),
|
||||
@JsonSubTypes.Type(value=Feature.class, name="Feature" ),
|
||||
@JsonSubTypes.Type(value=FeatureCollection.class, name="FeatureCollection" ),
|
||||
@JsonSubTypes.Type(value=GeometryCollection.class, name="GeometryCollection" )
|
||||
} )
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder({"type", "coordinates", "bbox"})
|
||||
public abstract class Geometry extends GeoJSON {
|
||||
@JsonCreator
|
||||
public Geometry() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
@JsonPropertyOrder({"type", "geometries"})
|
||||
public class GeometryCollection extends Geometry {
|
||||
private final Geometry[] geometries;
|
||||
|
||||
@JsonCreator
|
||||
public GeometryCollection(@JsonProperty("geometries") Geometry[] geometries) {
|
||||
super();
|
||||
this.geometries = geometries;
|
||||
}
|
||||
|
||||
public Geometry[] getGeometries() {
|
||||
return geometries;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class LineString extends Geometry {
|
||||
private final double[][] coordinates;
|
||||
private final double[] bbox;
|
||||
|
||||
@JsonCreator
|
||||
public LineString(@JsonProperty("coordinates") double [][] coordinates) {
|
||||
super();
|
||||
this.coordinates = coordinates;
|
||||
this.bbox = null;
|
||||
}
|
||||
|
||||
public double[][] getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public double[] getBbox() {
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class MultiLineString extends Geometry {
|
||||
private final double[][][] coordinates;
|
||||
private final double[] bbox;
|
||||
|
||||
@JsonCreator
|
||||
public MultiLineString(@JsonProperty("coordinates") double [][][] coordinates) {
|
||||
super();
|
||||
this.coordinates = coordinates;
|
||||
this.bbox = null;
|
||||
}
|
||||
|
||||
public double[][][] getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public double[] getBbox() {
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class MultiPoint extends Geometry {
|
||||
private final double[][] coordinates;
|
||||
private final double[] bbox;
|
||||
|
||||
@JsonCreator
|
||||
public MultiPoint(@JsonProperty("coordinates") double [][] coordinates) {
|
||||
super();
|
||||
this.coordinates = coordinates;
|
||||
this.bbox = null;
|
||||
}
|
||||
|
||||
public double[][] getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public double[] getBbox() {
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class MultiPolygon extends Geometry {
|
||||
private final double[][][][] coordinates;
|
||||
private final double[] bbox;
|
||||
|
||||
@JsonCreator
|
||||
public MultiPolygon(@JsonProperty("coordinates") double [][][][] coordinates) {
|
||||
super();
|
||||
this.coordinates = coordinates;
|
||||
this.bbox = null;
|
||||
}
|
||||
|
||||
public double[][][][] getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public double[] getBbox() {
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class Point extends Geometry {
|
||||
private final double[] coordinates;
|
||||
private final double[] bbox;
|
||||
|
||||
@JsonCreator
|
||||
public Point(@JsonProperty("coordinates") double [] coordinates) {
|
||||
super();
|
||||
this.coordinates = coordinates;
|
||||
this.bbox = null;
|
||||
}
|
||||
|
||||
public double[] getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public double[] getBbox() {
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package org.meteoinfo.geometry.io.geojson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
public class Polygon extends Geometry {
|
||||
private final double[][][] coordinates;
|
||||
private final double[] bbox;
|
||||
|
||||
@JsonCreator
|
||||
public Polygon(@JsonProperty("coordinates") double [][][] coordinates) {
|
||||
super();
|
||||
this.coordinates = coordinates;
|
||||
this.bbox = null;
|
||||
}
|
||||
|
||||
public double[][][] getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public double[] getBbox() {
|
||||
return bbox;
|
||||
}
|
||||
}
|
||||
@ -94,6 +94,7 @@ public class PointZ extends PointD implements Cloneable{
|
||||
* To double array
|
||||
* @return Double array
|
||||
*/
|
||||
@Override
|
||||
public double[] toArray() {
|
||||
return new double[]{X, Y, Z};
|
||||
}
|
||||
@ -102,6 +103,7 @@ public class PointZ extends PointD implements Cloneable{
|
||||
* To float array
|
||||
* @return Float array
|
||||
*/
|
||||
@Override
|
||||
public float[] toFloatArray() {
|
||||
return new float[]{(float) X, (float) Y, (float) Z};
|
||||
}
|
||||
|
||||
@ -39,6 +39,15 @@ public class PointZShape extends PointShape {
|
||||
this.updateExtent((PointZ)this.point);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param pointZ The PointZ object
|
||||
*/
|
||||
public PointZShape(PointZ pointZ) {
|
||||
this.point = pointZ;
|
||||
this.updateExtent(pointZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param geometry Geometry
|
||||
|
||||
@ -77,19 +77,6 @@ public class Polygon {
|
||||
return this._holeLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hole lines
|
||||
*
|
||||
* @return hole lines
|
||||
*/
|
||||
public List<List<? extends PointD>> getHoleLines_bak() {
|
||||
List<List<? extends PointD>> hlines = new ArrayList<>();
|
||||
for (List<? extends PointD> hline : _holeLines){
|
||||
hlines.add((List<PointD>)hline);
|
||||
}
|
||||
return hlines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a hole line
|
||||
* @param idx Index
|
||||
|
||||
@ -150,6 +150,14 @@ public class PolygonShape extends Shape implements Cloneable {
|
||||
return ShapeTypes.POLYGON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get is multi polygon or not
|
||||
* @return Multi polygon or not
|
||||
*/
|
||||
public boolean isMultiPolygon() {
|
||||
return this._numParts > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* To geometry method
|
||||
*
|
||||
@ -279,6 +287,15 @@ public class PolygonShape extends Shape implements Cloneable {
|
||||
return _polygons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a polygon
|
||||
* @param index The polygon index
|
||||
* @return The polygon
|
||||
*/
|
||||
public Polygon getPolygon(int index) {
|
||||
return _polygons.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set polygons
|
||||
*
|
||||
|
||||
@ -58,6 +58,14 @@ public class PolylineShape extends Shape implements Cloneable {
|
||||
_polylines = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param points Point list
|
||||
*/
|
||||
public PolylineShape(List<PointD> points) {
|
||||
this.setPoints(points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -109,6 +117,14 @@ public class PolylineShape extends Shape implements Cloneable {
|
||||
return ShapeTypes.POLYLINE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get is multi line or not
|
||||
* @return Multi line or not
|
||||
*/
|
||||
public boolean isMultiLine() {
|
||||
return this._numParts > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* To geometry method
|
||||
*
|
||||
|
||||
@ -42,6 +42,14 @@ public class PolylineZShape extends PolylineShape {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param points Points
|
||||
*/
|
||||
public PolylineZShape(List<PointZ> points) {
|
||||
this.setPoints(points);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param geometry Geometry
|
||||
|
||||
@ -1,32 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<MeteoInfo File="milconfig.xml" Type="configurefile">
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\meteo\wrf">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\jogl"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\chart\legend"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\wind"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\map\webmap"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<Path OpenPath="D:\Working\MIScript\Jython\mis\io\json">
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\netcdf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\meteo\wrf"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\ascii"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\cuace_dust"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\cuace_dust\py"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\traj"/>
|
||||
<RecentFolder Folder="D:\Working\MIScript\Jython\mis\io\json"/>
|
||||
</Path>
|
||||
<File>
|
||||
<OpenedFiles>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\wind\streamplot_cdata_map_1.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth\plot_cuace_earth_isosurface_streamline.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\meteo\wrf\wrf_destagger_uv_webmap.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\json\test_geojson_file_read_write.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
|
||||
<OpenedFile File="D:\Working\MIScript\Jython\mis\io\json\hy_conc_nuclear_geojson.py"/>
|
||||
</OpenedFiles>
|
||||
<RecentFiles>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\wind\streamplot_cdata_map_1.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\plot_types\3d\3d_earth\plot_cuace_earth_isosurface_streamline.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\meteo\wrf\wrf_destagger_uv_webmap.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\json\test_geojson_file_read_write.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\traj\hy_conc_geojson.py"/>
|
||||
<RecentFile File="D:\Working\MIScript\Jython\mis\io\json\hy_conc_nuclear_geojson.py"/>
|
||||
</RecentFiles>
|
||||
</File>
|
||||
<Font>
|
||||
@ -34,5 +34,5 @@
|
||||
</Font>
|
||||
<LookFeel DockWindowDecorated="true" LafDecorated="true" Name="FlatDarkLaf"/>
|
||||
<Figure DoubleBuffering="true"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1383,794"/>
|
||||
<Startup MainFormLocation="-7,0" MainFormSize="1330,805"/>
|
||||
</MeteoInfo>
|
||||
|
||||
Binary file not shown.
@ -17,6 +17,7 @@ from org.meteoinfo.projection import ProjectionUtil, KnownCoordinateSystems
|
||||
from org.meteoinfo.geometry.shape import PolygonShape, ShapeTypes
|
||||
from org.meteoinfo.geo.analysis import GeometryUtil
|
||||
from org.meteoinfo.geo.util import GeoProjectionUtil
|
||||
from org.meteoinfo.geo.io import GeoJSONReader, GeoJSONWriter
|
||||
|
||||
|
||||
class MILayer(object):
|
||||
@ -277,6 +278,14 @@ class MILayer(object):
|
||||
for shape, field in zip(shapes, fields):
|
||||
self._layer.editAddShape(shape, field)
|
||||
|
||||
def del_shape(self, shape):
|
||||
"""
|
||||
Delete a shape.
|
||||
|
||||
:param shape: (*Shape or int*) The shape or shape index to be deleted.
|
||||
"""
|
||||
self._layer.editRemoveShape(shape)
|
||||
|
||||
def copy(self):
|
||||
"""
|
||||
Copy the layer.
|
||||
@ -547,7 +556,7 @@ class MILayer(object):
|
||||
else:
|
||||
self._layer.saveFile(fn, encoding)
|
||||
|
||||
def savekml(self, fn):
|
||||
def save_kml(self, fn):
|
||||
"""
|
||||
Save layer as KML file.
|
||||
|
||||
@ -555,7 +564,7 @@ class MILayer(object):
|
||||
"""
|
||||
self._layer.saveAsKMLFile(fn)
|
||||
|
||||
def savebil(self, fn, proj=None):
|
||||
def save_bil(self, fn, proj=None):
|
||||
"""
|
||||
Save layer as bil file.
|
||||
|
||||
@ -567,6 +576,27 @@ class MILayer(object):
|
||||
else:
|
||||
self._layer.saveFile(fn, proj)
|
||||
|
||||
def save_geojson(self, fn):
|
||||
"""
|
||||
Save layer as GeoJSON file.
|
||||
|
||||
:param fn: (*str*) GeoJSON file name.
|
||||
"""
|
||||
features = GeoJSONWriter.write(self._layer)
|
||||
with open(fn, 'w') as f:
|
||||
f.write("{\n")
|
||||
f.write(""""type": "FeatureCollection",\n""")
|
||||
f.write(""""features": [\n""")
|
||||
for i in range(features.getNumFeatures()):
|
||||
feature = features.getFeature(i)
|
||||
f.write(feature.toString())
|
||||
if i < features.getNumFeatures() - 1:
|
||||
f.write(",\n")
|
||||
else:
|
||||
f.write("\n")
|
||||
f.write("]\n")
|
||||
f.write("}")
|
||||
|
||||
|
||||
class MIXYListData():
|
||||
def __init__(self, data=None):
|
||||
|
||||
2
pom.xml
2
pom.xml
@ -34,7 +34,7 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<revision>3.7.8</revision>
|
||||
<revision>3.7.9</revision>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<maven.compiler.release>8</maven.compiler.release>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user