【问题标题】:How to handle WKT data in Android?如何在 Android 中处理 WKT 数据?
【发布时间】:2012-09-11 11:22:30
【问题描述】:

我有这种格式的数据:

POINT(73.0166738279393 33.6788721326803)
MULTILINESTRING((73.0131224998036 33.679001500419,73.0119635003153 33.678392400389,73.0119205001311 33.6783781002692),(73.0131224998036 33.679001500419,73.0136031002029 33.6783443999742),(73.0136031002029 33.6783443999742,73.0147099372139 33.67685138958),(73.0147099372139 33.67685138958,73.0150124997272 33.6770292997624,73.0154158996241 33.6773507003746,73.0157677998441 33.6776577999676,73.016042399737 33.6779721004322,73.0162998999205 33.6783149004124,73.0166738279393 33.6788721326803))

现在我想在 Android 的 Google 地图上绘制它。我制作了一组名称和坐标。

ArrayList<String> coordinates = new ArrayList<String>
coordinates.add(tvcoor.getText().toString());

这会产生一个错误:当我运行我的应用程序时,它会强制停止。 以及如何在地图上绘制它?

【问题讨论】:

  • Gilles 我添加了 if 语句,因为 textView 还收到了另一个数据。但我只想将数据存储到数组列表中
  • 谢谢我至少解决了我的错误
  • 告诉我这段代码对于将值添加到数组列表表单中是否正确 textviewif((tvTextIn.equals(new String ("POINT")))||(tvTextIn.equals(new String ("MULTILINES ")))) {坐标.add(tvcoor.getText().toString()); }
  • 当我运行这段代码时它不在数组列表中存储值所有值都是空它创建了一个大小但都是空的
  • 你得到 textview 的值了吗? .请发布您的完整代码。

标签: android google-maps wkt


【解决方案1】:

试试这个,

String str;
ArrayList<String> coordinates = new ArrayList<String>();

首先从 textview 中获取字符串。

str = textview.getText().toString();

第二次删除括号。

str = str.replaceAll("\\(", "");
str = str.replaceAll("\\)", "");

然后用逗号分割,给arraylist加上值。

String[] commatokens = str.split(",");
        for (String commatoken : commatokens) {
            System.out.println("-" + commatoken + "-");
            coordinates.add(commatoken);
        }

然后我们在索引位置获得单独的坐标值,

 for (int i = 0; i < coordinates.size(); i++) {

            String[] tokens = coordinates.get(i).split("\\s");
            for (String token : tokens) {
                System.out.println("-" + token + "-");
            }
        }

【讨论】:

  • 感谢 rajesh 的帮助,但我无法理解最后一步以及当我在 mapactivity 中发送这个 coordiantes arraylist,然后从 mapactivity 到覆盖类并绘制一个点时
  • Intent in = getIntent(); loc = in.getStringArrayListExtra("stringname"); mapOverlays = mapView.getOverlays(); proj = mapView.getProjection();覆盖=新MyOverlay(位置);并画一个像这样的点 public MyOverlay(List locations) { // TODO 自动生成的构造函数存根 GeoPoint mp = new GeoPoint((int)(Integer.parseInt(locations.get(0))*1E6), ( int)(Integer.parseInt(locations.get(1))*1E6));然后应用程序意外停止
  • 它在第一位置的一些问题可以节省[0] = POINT(73.0166738279393 33.6788721326803)MULTILINESTRING((73.0131224998036 33.679001500419; [1] = 73.0119635003153 33.678392400389;然后再次[2] = POINT(73.0166738279393 33.6788721326803)多行字符串((73.0131224998036 33.679001500419;
  • 当我使用 \\s 时它不会拆分第一行,而当我使用 " " 时它会拆分最后一个值
  • 感谢 rajesh 的大力帮助,我已经解决了这个问题。现在去谷歌地图上画画
【解决方案2】:

对于遇到相同情况的其他人,我发现了一个名为JTS Topology Suite 的开源库,它能够解析Java 中的WKT 字符串。我的应用程序中的一个基本示例如下所示:

WKTReader wktReader = new WKTReader();
Geometry geometry = wktReader.read(routeResponse.get(yourWKTMultilineString);

然后您可以像这样遍历各个行:

for(int lineIndex = 0; lineIndex < geometry.getNumGeometries(); lineIndex++){
    Geometry lineGeometry = geometry.getGeometryN(lineIndex);
    //... other stuff
}

如果需要,您可以像这样获取每条线的单独坐标:

Coordinate[] lineCoordinates = lineGeometry.getCoordinates();

请注意,以上是遵循 OP 代码的非常通用的示例。

最终,这可能会使其他人不必推出自己的 WKT 解析器。


Nutiteq 特定代码:
就我而言,我需要在Nutiteq map 上绘制一个多行字符串作为矢量图层。我意识到 OP 询问的是 google map android API,但是如果任何读者也在使用 Nutiteq(或者如果该算法与其他地图 API 相关),这是 nutiteq 特定代码:

geomLayer.clear(); // clear the old vector data

Projection projection = geomLayer.getProjection(); // Map's projection type

// Iterate through the individual lines of our multi-line geometry
for(int lineIndex = 0; lineIndex < geometry.getNumGeometries(); lineIndex++){
    Geometry lineGeometry = geometry.getGeometryN(lineIndex);
    ArrayList<MapPos> linePositions = new ArrayList<MapPos>(lineGeometry.getCoordinates().length);

    // Iterate through this line's coordinates
    for(Coordinate coordinate : lineGeometry.getCoordinates()){
        // My server returns coordinates in WGS84/EPSG:4326 projection while the map
        // uses EPSG3857, so it is necessary to convert before adding to the
        // array list.
        MapPos linePosition = new MapPos(projection.fromWgs84(coordinate.x, coordinate.y));
        linePositions.add(linePosition);
    }

    // Finally, add the line data to the vector layer
    Line line = new Line(linePositions, new DefaultLabel("some label"), lineStyle), null);
    geomLayer.add(line);
}

请注意,lineStyleSetgeomLayer 是之前在活动的 onCreate 中创建的,可以研究 heregeomLayer 很简单;这是我的lineStyleSet

注意lineStyle,它是之前创建的,并保存为实例变量,如下所示:

Bitmap lineMarker = UnscaledBitmapLoader.decodeResource(getResources(), R.drawable.line);

this.lineStyleSet = new StyleSet<LineStyle>();
LineStyle lineStyle = LineStyle.builder().setLineJoinMode(LineStyle.NO_LINEJOIN).setWidth(0.2f).setColor(Color.RED).setBitmap(lineMarker).build();
lineStyleSet.setZoomStyle(minZoom, lineStyle);

【讨论】:

    【解决方案3】:

    WKT(众所周知的文本)文件描述了 ISO 19107 几何。就我个人而言,我尽量避免重新发明轮子,或者在自己编写的解析器中“弄乱”它们(你永远不知道,你的函数是否仅仅因为它工作了一次就涵盖了所有情况)。

    这是另一个漂亮的开源 API,带有示例和教程:

    http://docs.geotools.org/

    这里是 WKTParser 类

    http://docs.geotools.org/stable/javadocs/org/geotools/geometry/text/WKTParser.html

    Android 工作室: 只需将此添加到您的应用程序build.gradle 文件中:

    dependencies {
        /* your other dependencies */
        compile 'org.opengis:geoapi:3.0.0'
    }
    

    【讨论】:

      【解决方案4】:

      这是我编写的一个函数,用于将 WKT 中给出的 简单(无孔等)多边形转换为 LatLang 数组:

      public static LatLng[] GetPolygonPoints(String poligonWkt){
          ArrayList<LatLng> points = new ArrayList<LatLng>();
          Pattern p = Pattern.compile("(\\d*\\.\\d+)\\s(\\d*\\.\\d+)");
          Matcher m = p.matcher(poligonWkt);
          String point;
      
          while (m.find()){
              point =  poligonWkt.substring(m.start(), m.end());
              points.add(new LatLng(Double.parseDouble(m.group(2)), Double.parseDouble(m.group(1))));
          }
          return points.toArray(new LatLng[points.size()]);
      }
      

      然后您可以使用数组在地图上添加多边形:

      LatLng[] points = GeographyHelper.GetPolygonPoints(shapeWkt);
      
      Polygon p = mMap.addPolygon(
         new PolygonOptions()
            .add(points)
            .strokeWidth(4)
            .strokeColor(Color.RED));
      

      【讨论】:

        【解决方案5】:

        只是为了扩展保罗的回答,因为他的回答对我帮助很大......

        private void setUpMap(SomeObjectWithLocationAsWKT r) {
        
            List<LatLng> points = new ArrayList<LatLng>();
            WKTReader wktReader = new WKTReader();
            LineString line = null;
            Coordinate lineCentroid = null;
            Coordinate[] lineCoordinates = null;
        
            // if our object's WKT geometry is not null - map it
            if (r.geowkt != null) {
        
                // use the JTS (Java Topology Suite) WKTReader to read that WKT!
                try {
                    line = (LineString) wktReader.read(r.geowkt);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        
                // using (JTS) again to getCoordinates of the linestring
                lineCoordinates = line.getCoordinates();
        
                // Iterate through the line's coordinates & assign to List<LatLng> points
                for(Coordinate coordinate : lineCoordinates){
                    points.add(new LatLng(coordinate.x, coordinate.y));
                }
        
                // add Polyline to Google Map
                Polyline p = mMap.addPolyline(
                new PolylineOptions()
                .addAll(points)
                .width(4)
                .color(Color.RED));
            }
        }
        
        // an example of zooming to the centroid of the WKT geometry 
        // again, using (JTS - Java Topology Suite)
        private void handleNewLocation(Location location) {
            LatLng latLng = null; 
            WKTReader wktReader = new WKTReader();
            LineString line = null;
            Coordinate lineCentroid = null; 
        
            // if our object's WKT geometry is not null - zoom to it
            if (r.geowkt != null) {
                try {
                    line = (LineString) wktReader.read(r.geowkt);
                    lineCentroid = line.getCentroid().getCoordinate();
                    latLng = new LatLng(lineCentroid.x, lineCentroid.y);
                } catch (ParseException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else {
                // just default to whatever location was passed in
                Log.d(TAG, location.toString());
                double currentLatitude = location.getLatitude();
                double currentLongitude = location.getLongitude();
                latLng = new LatLng(currentLatitude, currentLongitude);
            }
            CameraUpdate yourLocation = CameraUpdateFactory.newLatLngZoom(latLng, 19);
            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
            mMap.animateCamera(yourLocation);
        }
        

        【讨论】:

        • 众所周知的文本标准涵盖了各种地理空间对象,而且这个解决方案似乎 - 至少尝试 - 将其转换为 LineString。它可能会崩溃。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-02-22
        • 2014-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-21
        • 1970-01-01
        相关资源
        最近更新 更多