Jak narysować ścieżkę na mapie za pomocą pliku kml?

96

Czy mogę przeanalizować plik kml, aby wyświetlić ścieżki lub punkty w systemie Android? Czy mógłbyś mi w tym pomóc?

Oto przykładowy kod kml, który chciałbym wyświetlić na mapie google android:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Paths</name>
<description>Examples of paths. Note that the tessellate tag is by default
  set to 0. If you want to create tessellated lines, they must be authored
  (or edited) directly in KML.</description>
<Style id="yellowLineGreenPoly">
  <LineStyle>
    <color>7f00ffff</color>
    <width>4</width>
  </LineStyle>
  <PolyStyle>
    <color>7f00ff00</color>
  </PolyStyle>
</Style>
<Placemark>
  <name>Absolute Extruded</name>
  <description>Transparent green wall with yellow outlines</description>
  <styleUrl>#yellowLineGreenPoly</styleUrl>
  <LineString>
    <extrude>1</extrude>
    <tessellate>1</tessellate>
    <altitudeMode>absolute</altitudeMode>
    <coordinates> -112.2550785337791,36.07954952145647,2357
      -112.2549277039738,36.08117083492122,2357
      -112.2552505069063,36.08260761307279,2357
      -112.2564540158376,36.08395660588506,2357
      -112.2580238976449,36.08511401044813,2357
      -112.2595218489022,36.08584355239394,2357
      -112.2608216347552,36.08612634548589,2357
      -112.262073428656,36.08626019085147,2357
      -112.2633204928495,36.08621519860091,2357
      -112.2644963846444,36.08627897945274,2357
      -112.2656969554589,36.08649599090644,2357 
    </coordinates>
    <LineString>
    </Placemark>
    </Document>
    </kml>

Kiedy ładuję ten plik do standardowej mapy internetowej google, ładnie go wyświetla, ale kiedy próbuję tego samego z mapą Google na Androida, nie robi tego. Po prostu przenosi mnie do niektórych miejsc i to wszystko. Myślałem o zmianie klasy słuchacza. Obecnie wygląda to tak:

private class MyLocationListener implements LocationListener 
{
    @Override
    public void onLocationChanged(Location loc) {
        if (loc != null) {
            latitude = (loc.getLatitude() * 1E6);
            longitude = (loc.getLongitude() * 1E6);
             Toast.makeText(getBaseContext(), 
                     "Location changed : Lat: " + latitude + 
                     " Lng: " + longitude, 
                     Toast.LENGTH_SHORT).show();

             GeoPoint p = new GeoPoint(
                     (int) (loc.getLatitude() * 1E6), 
                     (int) (loc.getLongitude() * 1E6));

             mc.animateTo(p);
             mapView.invalidate();
           }
    }

//---------------------------------------------------------------
    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onStatusChanged(String provider, int status, 
        Bundle extras) {
        //TODO Auto-generated method stub
    }

Czy ktoś może mi powiedzieć, co tu robię źle?

Pavel
źródło

Odpowiedzi:

115

W powyższym kodzie nie przekazujesz danych kml do swojego mapView nigdzie w kodzie, o ile widzę. Aby wyświetlić trasę, należy przeanalizować dane kml, np. Przez parser SAX, a następnie wyświetlić znaczniki trasy na mapie.

Zobacz poniższy kod, aby zapoznać się z przykładem, ale nie jest on kompletny - tylko dla Ciebie jako odniesienie i zdobądź jakiś pomysł.

To jest prosta fasola, której używam do przechowywania informacji o trasie, które będę analizować.

package com.myapp.android.model.navigation;

import java.util.ArrayList;
import java.util.Iterator;


public class NavigationDataSet { 

private ArrayList<Placemark> placemarks = new ArrayList<Placemark>();
private Placemark currentPlacemark;
private Placemark routePlacemark;

public String toString() {
    String s= "";
    for (Iterator<Placemark> iter=placemarks.iterator();iter.hasNext();) {
        Placemark p = (Placemark)iter.next();
        s += p.getTitle() + "\n" + p.getDescription() + "\n\n";
    }
    return s;
}

public void addCurrentPlacemark() {
    placemarks.add(currentPlacemark);
}

public ArrayList<Placemark> getPlacemarks() {
    return placemarks;
}

public void setPlacemarks(ArrayList<Placemark> placemarks) {
    this.placemarks = placemarks;
}

public Placemark getCurrentPlacemark() {
    return currentPlacemark;
}

public void setCurrentPlacemark(Placemark currentPlacemark) {
    this.currentPlacemark = currentPlacemark;
}

public Placemark getRoutePlacemark() {
    return routePlacemark;
}

public void setRoutePlacemark(Placemark routePlacemark) {
    this.routePlacemark = routePlacemark;
}

}

I program obsługi SAX do analizowania kml:

package com.myapp.android.model.navigation;

import android.util.Log;
import com.myapp.android.myapp;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.myapp.android.model.navigation.NavigationDataSet;
import com.myapp.android.model.navigation.Placemark;


public class NavigationSaxHandler extends DefaultHandler{ 

 // =========================================================== 
 // Fields 
 // =========================================================== 

 private boolean in_kmltag = false; 
 private boolean in_placemarktag = false; 
 private boolean in_nametag = false;
 private boolean in_descriptiontag = false;
 private boolean in_geometrycollectiontag = false;
 private boolean in_linestringtag = false;
 private boolean in_pointtag = false;
 private boolean in_coordinatestag = false;

 private StringBuffer buffer;

 private NavigationDataSet navigationDataSet = new NavigationDataSet(); 

 // =========================================================== 
 // Getter & Setter 
 // =========================================================== 

 public NavigationDataSet getParsedData() {
      navigationDataSet.getCurrentPlacemark().setCoordinates(buffer.toString().trim());
      return this.navigationDataSet; 
 } 

 // =========================================================== 
 // Methods 
 // =========================================================== 
 @Override 
 public void startDocument() throws SAXException { 
      this.navigationDataSet = new NavigationDataSet(); 
 } 

 @Override 
 public void endDocument() throws SAXException { 
      // Nothing to do
 } 

 /** Gets be called on opening tags like: 
  * <tag> 
  * Can provide attribute(s), when xml was like: 
  * <tag attribute="attributeValue">*/ 
 @Override 
 public void startElement(String namespaceURI, String localName, 
           String qName, Attributes atts) throws SAXException { 
      if (localName.equals("kml")) { 
           this.in_kmltag = true;
      } else if (localName.equals("Placemark")) { 
           this.in_placemarktag = true; 
           navigationDataSet.setCurrentPlacemark(new Placemark());
      } else if (localName.equals("name")) { 
           this.in_nametag = true;
      } else if (localName.equals("description")) { 
          this.in_descriptiontag = true;
      } else if (localName.equals("GeometryCollection")) { 
          this.in_geometrycollectiontag = true;
      } else if (localName.equals("LineString")) { 
          this.in_linestringtag = true;              
      } else if (localName.equals("point")) { 
          this.in_pointtag = true;          
      } else if (localName.equals("coordinates")) {
          buffer = new StringBuffer();
          this.in_coordinatestag = true;                        
      }
 } 

 /** Gets be called on closing tags like: 
  * </tag> */ 
 @Override 
 public void endElement(String namespaceURI, String localName, String qName) 
           throws SAXException { 
       if (localName.equals("kml")) {
           this.in_kmltag = false; 
       } else if (localName.equals("Placemark")) { 
           this.in_placemarktag = false;

       if ("Route".equals(navigationDataSet.getCurrentPlacemark().getTitle())) 
               navigationDataSet.setRoutePlacemark(navigationDataSet.getCurrentPlacemark());
        else navigationDataSet.addCurrentPlacemark();

       } else if (localName.equals("name")) { 
           this.in_nametag = false;           
       } else if (localName.equals("description")) { 
           this.in_descriptiontag = false;
       } else if (localName.equals("GeometryCollection")) { 
           this.in_geometrycollectiontag = false;
       } else if (localName.equals("LineString")) { 
           this.in_linestringtag = false;              
       } else if (localName.equals("point")) { 
           this.in_pointtag = false;          
       } else if (localName.equals("coordinates")) { 
           this.in_coordinatestag = false;
       }
 } 

 /** Gets be called on the following structure: 
  * <tag>characters</tag> */ 
 @Override 
public void characters(char ch[], int start, int length) { 
    if(this.in_nametag){ 
        if (navigationDataSet.getCurrentPlacemark()==null) navigationDataSet.setCurrentPlacemark(new Placemark());
        navigationDataSet.getCurrentPlacemark().setTitle(new String(ch, start, length));            
    } else 
    if(this.in_descriptiontag){ 
        if (navigationDataSet.getCurrentPlacemark()==null) navigationDataSet.setCurrentPlacemark(new Placemark());
        navigationDataSet.getCurrentPlacemark().setDescription(new String(ch, start, length));          
    } else
    if(this.in_coordinatestag){        
        if (navigationDataSet.getCurrentPlacemark()==null) navigationDataSet.setCurrentPlacemark(new Placemark());
        //navigationDataSet.getCurrentPlacemark().setCoordinates(new String(ch, start, length));
        buffer.append(ch, start, length);
    }
} 
}

i proste miejsce

package com.myapp.android.model.navigation;

public class Placemark {

String title;
String description;
String coordinates;
String address;

public String getTitle() {
    return title;
}
public void setTitle(String title) {
    this.title = title;
}
public String getDescription() {
    return description;
}
public void setDescription(String description) {
    this.description = description;
}
public String getCoordinates() {
    return coordinates;
}
public void setCoordinates(String coordinates) {
    this.coordinates = coordinates;
}
public String getAddress() {
    return address;
}
public void setAddress(String address) {
    this.address = address;
}

}

Wreszcie klasa usług w moim modelu, która wywołuje obliczenia:

package com.myapp.android.model.navigation;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import com.myapp.android.myapp;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.util.Log;

public class MapService {

public static final int MODE_ANY = 0;
public static final int MODE_CAR = 1;
public static final int MODE_WALKING = 2;


public static String inputStreamToString (InputStream in) throws IOException {
    StringBuffer out = new StringBuffer();
    byte[] b = new byte[4096];
    for (int n; (n = in.read(b)) != -1;) {
        out.append(new String(b, 0, n));
    }
    return out.toString();
}


public static NavigationDataSet calculateRoute(Double startLat, Double startLng, Double targetLat, Double targetLng, int mode) {
    return calculateRoute(startLat + "," + startLng, targetLat + "," + targetLng, mode);
}

public static NavigationDataSet calculateRoute(String startCoords, String targetCoords, int mode) {
    String urlPedestrianMode = "http://maps.google.com/maps?" + "saddr=" + startCoords + "&daddr="
            + targetCoords + "&sll=" + startCoords + "&dirflg=w&hl=en&ie=UTF8&z=14&output=kml";

    Log.d(myapp.APP, "urlPedestrianMode: "+urlPedestrianMode);

    String urlCarMode = "http://maps.google.com/maps?" + "saddr=" + startCoords + "&daddr="
            + targetCoords + "&sll=" + startCoords + "&hl=en&ie=UTF8&z=14&output=kml";

    Log.d(myapp.APP, "urlCarMode: "+urlCarMode);

    NavigationDataSet navSet = null;
    // for mode_any: try pedestrian route calculation first, if it fails, fall back to car route
    if (mode==MODE_ANY||mode==MODE_WALKING) navSet = MapService.getNavigationDataSet(urlPedestrianMode);
    if (mode==MODE_ANY&&navSet==null||mode==MODE_CAR) navSet = MapService.getNavigationDataSet(urlCarMode);
    return navSet;
}

/**
 * Retrieve navigation data set from either remote URL or String
 * @param url
 * @return navigation set
 */
public static NavigationDataSet getNavigationDataSet(String url) {

    // urlString = "http://192.168.1.100:80/test.kml";
    Log.d(myapp.APP,"urlString -->> " + url);
    NavigationDataSet navigationDataSet = null;
    try
        {           
        final URL aUrl = new URL(url);
        final URLConnection conn = aUrl.openConnection();
        conn.setReadTimeout(15 * 1000);  // timeout for reading the google maps data: 15 secs
        conn.connect();

        /* Get a SAXParser from the SAXPArserFactory. */
        SAXParserFactory spf = SAXParserFactory.newInstance(); 
        SAXParser sp = spf.newSAXParser(); 

        /* Get the XMLReader of the SAXParser we created. */
        XMLReader xr = sp.getXMLReader();

        /* Create a new ContentHandler and apply it to the XML-Reader*/ 
        NavigationSaxHandler navSax2Handler = new NavigationSaxHandler(); 
        xr.setContentHandler(navSax2Handler); 

        /* Parse the xml-data from our URL. */ 
        xr.parse(new InputSource(aUrl.openStream()));

        /* Our NavigationSaxHandler now provides the parsed data to us. */ 
        navigationDataSet = navSax2Handler.getParsedData(); 

        /* Set the result to be displayed in our GUI. */ 
        Log.d(myapp.APP,"navigationDataSet: "+navigationDataSet.toString());

    } catch (Exception e) {
        // Log.e(myapp.APP, "error with kml xml", e);
        navigationDataSet = null;
    }   

    return navigationDataSet;
}

}

Rysunek:

/**
 * Does the actual drawing of the route, based on the geo points provided in the nav set
 *
 * @param navSet     Navigation set bean that holds the route information, incl. geo pos
 * @param color      Color in which to draw the lines
 * @param mMapView01 Map view to draw onto
 */
public void drawPath(NavigationDataSet navSet, int color, MapView mMapView01) {

    Log.d(myapp.APP, "map color before: " + color);        

    // color correction for dining, make it darker
    if (color == Color.parseColor("#add331")) color = Color.parseColor("#6C8715");
    Log.d(myapp.APP, "map color after: " + color);

    Collection overlaysToAddAgain = new ArrayList();
    for (Iterator iter = mMapView01.getOverlays().iterator(); iter.hasNext();) {
        Object o = iter.next();
        Log.d(myapp.APP, "overlay type: " + o.getClass().getName());
        if (!RouteOverlay.class.getName().equals(o.getClass().getName())) {
            // mMapView01.getOverlays().remove(o);
            overlaysToAddAgain.add(o);
        }
    }
    mMapView01.getOverlays().clear();
    mMapView01.getOverlays().addAll(overlaysToAddAgain);

    String path = navSet.getRoutePlacemark().getCoordinates();
    Log.d(myapp.APP, "path=" + path);
    if (path != null && path.trim().length() > 0) {
        String[] pairs = path.trim().split(" ");

        Log.d(myapp.APP, "pairs.length=" + pairs.length);

        String[] lngLat = pairs[0].split(","); // lngLat[0]=longitude lngLat[1]=latitude lngLat[2]=height

        Log.d(myapp.APP, "lnglat =" + lngLat + ", length: " + lngLat.length);

        if (lngLat.length<3) lngLat = pairs[1].split(","); // if first pair is not transferred completely, take seconds pair //TODO 

        try {
            GeoPoint startGP = new GeoPoint((int) (Double.parseDouble(lngLat[1]) * 1E6), (int) (Double.parseDouble(lngLat[0]) * 1E6));
            mMapView01.getOverlays().add(new RouteOverlay(startGP, startGP, 1));
            GeoPoint gp1;
            GeoPoint gp2 = startGP;

            for (int i = 1; i < pairs.length; i++) // the last one would be crash
            {
                lngLat = pairs[i].split(",");

                gp1 = gp2;

                if (lngLat.length >= 2 && gp1.getLatitudeE6() > 0 && gp1.getLongitudeE6() > 0
                        && gp2.getLatitudeE6() > 0 && gp2.getLongitudeE6() > 0) {

                    // for GeoPoint, first:latitude, second:longitude
                    gp2 = new GeoPoint((int) (Double.parseDouble(lngLat[1]) * 1E6), (int) (Double.parseDouble(lngLat[0]) * 1E6));

                    if (gp2.getLatitudeE6() != 22200000) { 
                        mMapView01.getOverlays().add(new RouteOverlay(gp1, gp2, 2, color));
                        Log.d(myapp.APP, "draw:" + gp1.getLatitudeE6() + "/" + gp1.getLongitudeE6() + " TO " + gp2.getLatitudeE6() + "/" + gp2.getLongitudeE6());
                    }
                }
                // Log.d(myapp.APP,"pair:" + pairs[i]);
            }
            //routeOverlays.add(new RouteOverlay(gp2,gp2, 3));
            mMapView01.getOverlays().add(new RouteOverlay(gp2, gp2, 3));
        } catch (NumberFormatException e) {
            Log.e(myapp.APP, "Cannot draw route.", e);
        }
    }
    // mMapView01.getOverlays().addAll(routeOverlays); // use the default color
    mMapView01.setEnabled(true);
}

To jest klasa RouteOverlay:

package com.myapp.android.activity.map.nav;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;

public class RouteOverlay extends Overlay { 

private GeoPoint gp1;
private GeoPoint gp2;
private int mRadius=6;
private int mode=0;
private int defaultColor;
private String text="";
private Bitmap img = null;

public RouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode) { // GeoPoint is a int. (6E)
    this.gp1 = gp1;
    this.gp2 = gp2;
    this.mode = mode;
    defaultColor = 999; // no defaultColor
}

public RouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode, int defaultColor) {
    this.gp1 = gp1;
    this.gp2 = gp2;
    this.mode = mode;
    this.defaultColor = defaultColor;
}

public void setText(String t) {
    this.text = t;
}

public void setBitmap(Bitmap bitmap) { 
    this.img = bitmap;
}

public int getMode() {
    return mode;
}

@Override
public boolean draw (Canvas canvas, MapView mapView, boolean shadow, long when) {
    Projection projection = mapView.getProjection();
    if (shadow == false) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        Point point = new Point();
        projection.toPixels(gp1, point);
        // mode=1&#65306;start
        if(mode==1) {
            if(defaultColor==999)
            paint.setColor(Color.BLACK); // Color.BLUE
            else
            paint.setColor(defaultColor);
            RectF oval=new RectF(point.x - mRadius, point.y - mRadius,
            point.x + mRadius, point.y + mRadius);
            // start point
            canvas.drawOval(oval, paint);
        }
        // mode=2&#65306;path
        else if(mode==2) {
            if(defaultColor==999)
            paint.setColor(Color.RED);
            else
            paint.setColor(defaultColor);
            Point point2 = new Point();
            projection.toPixels(gp2, point2);
            paint.setStrokeWidth(5);
            paint.setAlpha(defaultColor==Color.parseColor("#6C8715")?220:120);
            canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
        }
        /* mode=3&#65306;end */
        else if(mode==3) {
            /* the last path */

            if(defaultColor==999)
                paint.setColor(Color.BLACK);  // Color.GREEN
            else
                paint.setColor(defaultColor);

            Point point2 = new Point();
            projection.toPixels(gp2, point2);
            paint.setStrokeWidth(5);
            paint.setAlpha(defaultColor==Color.parseColor("#6C8715")?220:120);
            canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
            RectF oval=new RectF(point2.x - mRadius,point2.y - mRadius,
            point2.x + mRadius,point2.y + mRadius);
            /* end point */
            paint.setAlpha(255);
            canvas.drawOval(oval, paint);
        }
    }
    return super.draw(canvas, mapView, shadow, when);
}

}
Mathias Conradt
źródło
7
Również ten link może Cię zainteresować: csie-tw.blogspot.com/2009/06/…
Mathias
1
Czy możesz podać działający przykład kodu, który podałeś w SO? Może prosty przykład KML i SAxParsing.lub jakiejś strony internetowej z whee mogę ją pobrać. Jestem w tym nowy i wolę uczyć się na praktycznym przykładzie. Dziękuję Ci.
Rohan K
Nie mam samodzielnej próbki / apk tego. Moja próbka jest ściśle zintegrowana z komercyjną aplikacją, którą zrobiłem. Możesz pobrać dowolny kml z serwera internetowego map Google, po prostu obliczyć trasę, a następnie pobrać adres URL tej trasy z przeglądarki i dodać & output = kml do adresu URL, który da ci plik kml.
Mathias Conradt
Umieściłem wydruk w metodzie public void characters (char ch [], int start, int length), więc mogłem sprawdzić wszystkie przeanalizowane wartości. Prawie na końcu przeanalizowanego pliku podaje całkowitą odległość między dwoma punktami -> 900 & # 160; m (około 11 minut) <br/> Dane mapy & # 169; 2011 Google. Czy ktoś wie, jak uzyskać tę wartość? Czy potrzebujesz stworzyć dodatkowy tag w metodzie end- i startElement?
Vincent,
ostrzeżenie dla przyszłych poszukiwaczy tego kodu, metoda znaków () jest niepoprawna. nigdy nie należy zakładać, że pojedyncze wywołanie metody znaków () będzie zawierało całą zawartość tekstową znacznika.
jtahlborn
11

Dziękuję Mathiasowi Linowi, przetestowany i działa!

Ponadto przykładowa implementacja metody Mathiasa w działaniu może wyglądać następująco.

public class DirectionMapActivity extends MapActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.directionmap);

        MapView mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);

        // Acquire a reference to the system Location Manager
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

        String locationProvider = LocationManager.NETWORK_PROVIDER;
        Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);

        StringBuilder urlString = new StringBuilder();
        urlString.append("http://maps.google.com/maps?f=d&hl=en");
        urlString.append("&saddr=");//from
        urlString.append( Double.toString(lastKnownLocation.getLatitude() ));
        urlString.append(",");
        urlString.append( Double.toString(lastKnownLocation.getLongitude() ));
        urlString.append("&daddr=");//to
        urlString.append( Double.toString((double)dest[0]/1.0E6 ));
        urlString.append(",");
        urlString.append( Double.toString((double)dest[1]/1.0E6 ));
        urlString.append("&ie=UTF8&0&om=0&output=kml");

        try{
            // setup the url
            URL url = new URL(urlString.toString());
            // create the factory
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // create a parser
            SAXParser parser = factory.newSAXParser();
            // create the reader (scanner)
            XMLReader xmlreader = parser.getXMLReader();
            // instantiate our handler
            NavigationSaxHandler navSaxHandler = new NavigationSaxHandler();
            // assign our handler
            xmlreader.setContentHandler(navSaxHandler);
            // get our data via the url class
            InputSource is = new InputSource(url.openStream());
            // perform the synchronous parse           
            xmlreader.parse(is);
            // get the results - should be a fully populated RSSFeed instance, or null on error
            NavigationDataSet ds = navSaxHandler.getParsedData();

            // draw path
            drawPath(ds, Color.parseColor("#add331"), mapView );

            // find boundary by using itemized overlay
            GeoPoint destPoint = new GeoPoint(dest[0],dest[1]);
            GeoPoint currentPoint = new GeoPoint( new Double(lastKnownLocation.getLatitude()*1E6).intValue()
                                                ,new Double(lastKnownLocation.getLongitude()*1E6).intValue() );

            Drawable dot = this.getResources().getDrawable(R.drawable.pixel);
            MapItemizedOverlay bgItemizedOverlay = new MapItemizedOverlay(dot,this);
            OverlayItem currentPixel = new OverlayItem(destPoint, null, null );
            OverlayItem destPixel = new OverlayItem(currentPoint, null, null );
            bgItemizedOverlay.addOverlay(currentPixel);
            bgItemizedOverlay.addOverlay(destPixel);

            // center and zoom in the map
            MapController mc = mapView.getController();
            mc.zoomToSpan(bgItemizedOverlay.getLatSpanE6()*2,bgItemizedOverlay.getLonSpanE6()*2);
            mc.animateTo(new GeoPoint(
                    (currentPoint.getLatitudeE6() + destPoint.getLatitudeE6()) / 2
                    , (currentPoint.getLongitudeE6() + destPoint.getLongitudeE6()) / 2));

        } catch(Exception e) {
            Log.d("DirectionMap","Exception parsing kml.");
        }

    }
    // and the rest of the methods in activity, e.g. drawPath() etc...

MapItemizedOverlay.java

public class MapItemizedOverlay extends ItemizedOverlay{
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    private Context mContext;

    public MapItemizedOverlay(Drawable defaultMarker, Context context) {
          super(boundCenterBottom(defaultMarker));
          mContext = context;
    }

    public void addOverlay(OverlayItem overlay) {
        mOverlays.add(overlay);
        populate();
    }

    @Override
    protected OverlayItem createItem(int i) {
      return mOverlays.get(i);
    }

    @Override
    public int size() {
      return mOverlays.size();
    }

}
alvinsj
źródło
7
Cześć Alvinsj, czy jest możliwe upublicznienie działającego projektu, który pełni powyższą funkcję? Wielkie dzięki.
lionfly
6

Jest teraz dostępna wersja beta narzędzia do importowania plików KML z Map Google .

Jest częścią biblioteki narzędzi Google Maps Android API . Jak udokumentowano, umożliwia ładowanie plików KML ze strumieni

KmlLayer layer = new KmlLayer(getMap(), kmlInputStream, getApplicationContext());

lub zasoby lokalne

KmlLayer layer = new KmlLayer(getMap(), R.raw.kmlFile, getApplicationContext());

Po utworzeniu obiektu KmlLayer wywołaj addLayerToMap (), aby dodać zaimportowane dane do mapy.

layer.addLayerToMap();
ben-efiz
źródło
3

Kod Mathiasa Lin działa pięknie. Możesz jednak rozważyć zmianę tej części w metodzie drawPath:

 if (lngLat.length >= 2 && gp1.getLatitudeE6() > 0 && gp1.getLongitudeE6() > 0
                    && gp2.getLatitudeE6() > 0 && gp2.getLongitudeE6() > 0) {

GeoPoint może być również mniejszy niż zero, przełączam się na:

     if (lngLat.length >= 2 && gp1.getLatitudeE6() != 0 && gp1.getLongitudeE6() != 0
                    && gp2.getLatitudeE6() != 0 && gp2.getLongitudeE6() != 0) {

Dziękuję: D

RobGThai
źródło