How to handle WKT data in Android?

前端 未结 5 1254
傲寒
傲寒 2020-12-18 11:22

I have data in this format:

POINT(73.0166738279393 33.6788721326803)
MULTILINESTRING((73.0131224998036 33.679001500419,73.0119635003153 33.678392400389,73.01         


        
相关标签:
5条回答
  • 2020-12-18 11:37

    Try this ,

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

    First get string from textview.

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

    Second remove brackets.

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

    Then split with comma and add values to arraylist.

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

    Then we get separate coordinates value at index position ,

     for (int i = 0; i < coordinates.size(); i++) {
    
                String[] tokens = coordinates.get(i).split("\\s");
                for (String token : tokens) {
                    System.out.println("-" + token + "-");
                }
            }
    
    0 讨论(0)
  • 2020-12-18 11:38

    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);
    }
    
    0 讨论(0)
  • 2020-12-18 11:43

    For anyone else who has this same scenario, I found an open source library called JTS Topology Suite, which has the capability to parse WKT strings in Java. A basic example from my application looks like this:

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

    You can then iterate through the individual lines like so:

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

    If necessary, you can obtain the individual coordinates of each line like so:

    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);
    
    0 讨论(0)
  • 2020-12-18 11:53

    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));
    
    0 讨论(0)
  • 2020-12-18 12:00

    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'
    }
    
    0 讨论(0)
提交回复
热议问题