wkt转geojson (for MultiPolygon)

WKT(Well-known text)是一种文本标记语言,用于表示矢量几何对象、空间参照系统及空间参照系统之间的转换。它的二进制表示方式,亦即WKB(well-known-binary)则胜于在传输和在数据库中存储相同的信息。

GeoJSON是一种对各种地理数据结构进行编 码的格式,可以表示几何、特征或者特征集合。

点 POINT(6 10)

线 LINESTRING(44 4,11 44,33 25)

面 POLYGON((1 1,2 2,3 3,4 4,5 5,1 1),(11 11,2 13,34 43,34 42,52 52,11 11))

多点 MULTIPOINT(44 4,11 44,33 25)

多线 MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4))

多面 MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2)),((6 3,9 2,9 4,6 3)))

几何集合 GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))

对应geojson

点 {"type":"Point","coordinates":[6,10]}

线 {"type":"LineString","coordinates":[[44, 4],[11, 44],[33, 25]]}

面 {"type":"Polygon","coordinates":[[[1, 1],[2, 2],[3, 3],[4, 4],[5, 5],[1, 1]],[[11, 11],[2, 13],[34, 43],[34, 42],[52, 52],[11, 11]]]}

多点 {"type":"MultiPoint","coordinates":[[44, 4],[11, 44],[33, 25]]}

多线 {"type":"MultiLineString","coordinates":[[[3, 4],[10, 50],[20, 25]],[[-5, -8],[-10, -8],[-15, -4]]}

多面 {"type":"MultiPolygon","coordinates":[[[3, 4],[10, 50],[20, 25]],[[-5, -8],[-10, -8],[-15, -4]]]}

几何集合 {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[4,6]},},{"type":"Feature","geometry":{"type":"LineString","coordinates":[[[4,6],[7,10]]}]}

wkt 格式数据转为geojson 给google map使用

数据格式:

wkt: MULTIPOLYGON(((1 1,5 1,5 5,1 5,1 1),(2 2,2 3,3 3,3 2,2 2)),((6 3,9 2,9 4,6 3)))

geoJson: {"type":"MultiPolygon","coordinates":[[[[1,1],[5,1],[5,5],[1,5],[1,1]],[[2,2],[2,3],[3,3],[3,2],[2,2]]],[[[6,3],[9,2],[9,4],[6,3]]]]}

  • 导入 jts jar包 ,通过geometry来解析MultiPolygon等类型数据,代码如下

 public static final GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(),
     4326);
 public static final WKTReader wktReader = new WKTReader(geometryFactory);

 public static Geometry toGeometry(String wkt) throws ParseException {
   Geometry read = wktReader.read(wkt);
   return read;
 }

 public static JSONObject parsePolygon2Geojson(Geometry geom) throws ParseException {
   JSONObject jsonObject = new JSONObject();
   String type = geom.getGeometryType();
   jsonObject.put("type", geom.getGeometryType());
   if ("MultiPolygon".equalsIgnoreCase(type)) {
     JSONArray coordJson = new JSONArray();
     for (int i = 0; i < geom.getNumGeometries(); i++) {
       // polygon
       coordJson.add(parsePolygon(geom.getGeometryN(i)));
     }
     jsonObject.put("coordinates", coordJson);
   } else if ("Polygon".equalsIgnoreCase(type)) {
     jsonObject.put("coordinates", parsePolygon(geom));
   } else if ("MultiLineString".equalsIgnoreCase(type)) {
     JSONArray coordJson = new JSONArray();
     for (int i = 0; i < geom.getNumGeometries(); i++) {
       List<List<Double>> line = new ArrayList<>();
       // polygon
       for (Coordinate coordinate : geom.getGeometryN(i).getCoordinates()) {
         line.add(getPoint(coordinate));
       }
       coordJson.add(line);
     }
     jsonObject.put("coordinates", coordJson);
   } else if ("Point".equalsIgnoreCase(type)) {
     jsonObject.put("coordinates", getPoint(geom.getCoordinate()));
   } else if ("MultiPoint".equalsIgnoreCase(type) || "LineString".equalsIgnoreCase(type)) {
     List<List<Double>> coordJson = new ArrayList<>();
     for (Coordinate coordinate : geom.getCoordinates()) {
       coordJson.add(getPoint(coordinate));
     }
     jsonObject.put("coordinates", coordJson);
   } else {
     jsonObject.put("coordinates", new JSONArray());
   }
   return jsonObject;
 }

 private static JSONArray parsePolygon(Geometry geom) {
   // polygon
   JSONArray coordJson = new JSONArray();
   Polygon polygon = (Polygon) geom;
   LineString exteriorRing = polygon.getExteriorRing();
   exteriorRing.getCoordinateSequence();

   List<List<Double>> line = new ArrayList<>();
   for (Coordinate exterior : exteriorRing.getCoordinates()) {
     line.add(getPoint(exterior));
   }
   coordJson.add(line);
   for (int j = 0; j < polygon.getNumInteriorRing(); j++) {
     List<List<Double>> lineIn = new ArrayList<>();
     for (Coordinate internal : polygon.getInteriorRingN(j).getCoordinates()) {
       lineIn.add(getPoint(internal));
     }
     coordJson.add(lineIn);
   }
   return coordJson;
 }

 private static List<Double> getPoint(Coordinate exterior) {
   List<Double> point = new ArrayList();
   point.add(exterior.x);
   point.add(exterior.y);
//        li.add(coordinate.z);
   return point;
 }
  • 据观察wkt 与geojson 的数据关系可以发现一些规律,通过处理字符串的方式来转换,可以支持点,多点,线,多线,面,多面等数据,针对数据量复杂的数据用时大概十几ms,但是前提必须数据格式正确。不建议使用。 MULTILINESTRING((3 4,10 50,20 25),(-5 -8,-10 -8,-15 -4)) -> {"type":"MULTILINESTRING","coordinates":[[[3,4],[10,50],[20,25]],[[-5,-8],[-10,-8],[-15,-4]]]}
  public static JSONObject getGj(String wkt) {
    if (wkt == null) {
      return null;
    }
    if (wkt.contains("(")) {
      int index = wkt.indexOf("(");
      String type = wkt.substring(0, index);
      String value = wkt.substring(index);
      String t = value.replace("(", "[").replace(")", "]");
//        Pattern.compile("-?(0-9){1,3}(.0-9)*+\\s+-?(0-9){1,2}(.0-9)*+");
//      Pattern compile = Pattern.compile("[-.0-9]+\\s+[-.0-9]+\\s+[-.0-9]+");
      Pattern compile = Pattern.compile("[-.0-9]+\\s+[-.0-9]+");
      Matcher matcher = compile.matcher(t);
      StringBuilder sb = new StringBuilder();
      sb.append("{\"type\":\"" + type + "\",\"coordinates\":");
      int end = 0;
      int start;
      while (matcher.find()) {
        String group = matcher.group();
        start = matcher.start();
        String[] split = group.split("\\s+");
        sb.append(t.substring(end, start)).append("[").append(split[0]).append(",").append
            (split[1]).append("]");
        end = matcher.end();
      }
      sb.append(t.substring(end));
      sb.append("}");
      return JSONObject.fromObject(sb.toString());
    }
    return null;
  }

猜你喜欢

转载自my.oschina.net/u/3781121/blog/1621404