3

我有这种格式的数据:

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());

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

4

5 回答 5

2

试试这个 ,

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 + "-");
            }
        }
于 2012-09-17T07:51:24.567 回答
1

对于其他有同样情况的人,我发现了一个名为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();

Note that the above is a very general example which follows the OP's code.

Ultimately, this might save others from having to roll their own WKT parser.


Nutiteq-Specific Code:
In my case, I needed to draw a multiline string as a vector layer on a Nutiteq map. I realize the OP was asking about the google map android API, however in case any reader is also using Nutiteq (or if this algorithm is relevant for other map APIs), this is the nutiteq specific code:

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);
}

Note that the lineStyleSet and geomLayer are created previously in the activity's onCreate and can be researched here. The geomLayer is simple; here is my lineStyleSet:

Note about lineStyle, it was created previously and is saved as an instance variable, like so:

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);
于 2014-02-13T16:56:03.517 回答
1

A WKT (well-known-text) file describes an ISO 19107 Geometry. Personally I try to avoid re-inventing the wheel, or "mess" with them in self written parsers ( you never know, whether your function covers all situation just because it worked once).

So here's another nice looking open source API, with examples, tutorials:

http://docs.geotools.org/

And here the WKTParser class

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

Android Studio: Simply add this to your app build.gradle file:

dependencies {
    /* your other dependencies */
    compile 'org.opengis:geoapi:3.0.0'
}
于 2016-02-04T11:39:57.217 回答
0

Here is a function I wrote to convert a simple (no holes etc.) polygon given in WKT into an array of 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()]);
}

You can then use the array to add the polygon on the map:

LatLng[] points = GeographyHelper.GetPolygonPoints(shapeWkt);

Polygon p = mMap.addPolygon(
   new PolygonOptions()
      .add(points)
      .strokeWidth(4)
      .strokeColor(Color.RED));
于 2015-02-01T11:25:23.683 回答
0

Just to expand on Paul's answer, since his answer helped me so much...

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);
}
于 2015-10-30T16:52:06.647 回答