来自远程 XML 的 Google 地图 v2 上的标记

Markers on Google Maps v2 from remote XML

我在我的android项目

中设法渲染地图、获取位置等

但我正在努力寻找一些关于如何从远程 xml 文件在 google 地图 v2 上放置标记的基本或高级示例。

那么,如何从远程 xml 获取标记并使用 Google 地图 API v2 显示它们?

这里是 XML 文件格式的例子:

<?xml version="1.0" encoding="UTF-8"?>
<maintag>
   <item>
      <id>1</id>
      <name>Place</name>
      <lat>60.1736245</lat>
      <lng>12.0283267</lng>
      <description>Nice Place</description>
      <type>2</type>
      <spotid>191712</spotid>
      <image>placeimage</image>
   </item>
   <item>
      <id>2</id>
      <name>Place</name>
      <lat>61.1736245</lat>
      <lng>13.0283267</lng>
      <description>Nice Place</description>
      <type>3</type>
      <spotid>291712</spotid>
      <image>placeimage</image>
   </item>
</maintag>

您只需要在后台线程的网络操作中访问XML,解析XML,然后在UI线程上相应地显示标记。

我刚刚使用 this answer 作为 XML 解析的指南来完成这项工作。

进口:

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

这是完整的 Activity class,其中包括一个 AsyncTask 作为内部 class,它从 URL 下载并解析 XML doInBackground(),然后在onPostExecute()中绘制标记:

public class MapFromXML extends AppCompatActivity implements OnMapReadyCallback {

    GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_map_from_xml);
    }

    @Override
    public void onResume() {
        super.onResume();

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        if (mapFragment != null) {
            if (mMap == null) {
                mapFragment.getMapAsync(this);
            } else {
                new GetXmlAsync().execute();
            }
        }
    }

    @Override
    public void onPause() {
        super.onPause();
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        new GetXmlAsync().execute();
    }


    public class GetXmlAsync extends AsyncTask<URL, Void, List<MarkerInfo>> {

        @Override
        protected List<MarkerInfo> doInBackground(URL... params) {

            List<MarkerInfo> markerInfoList = new ArrayList<>();
            Document doc = null;
            URL url = null;
            try {
                url = new URL("http://www.example.com/GoogleMapXML.xml");

                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = null;
                db = dbf.newDocumentBuilder();
                doc = db.parse(new InputSource(url.openStream()));

            } catch (ParserConfigurationException e1) {
                e1.printStackTrace();
            } catch (MalformedURLException e1) {
                e1.printStackTrace();
            } catch (SAXException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();

            }

            doc.getDocumentElement().normalize();

            NodeList nodeList = doc.getElementsByTagName("item");

            try {
                for (int i = 0; i < nodeList.getLength(); i++) {

                    Node node = nodeList.item(i);
                    Element fstElmnt = (Element) node;

                    NodeList nameList = fstElmnt.getElementsByTagName("name");
                    Element nameElement = (Element) nameList.item(0);
                    nameList = nameElement.getChildNodes();
                    String name = ((Node) nameList.item(0)).getNodeValue();

                    NodeList latList = fstElmnt.getElementsByTagName("lat");
                    Element latElement = (Element) latList.item(0);
                    latList = latElement.getChildNodes();
                    String lat = ((Node) latList.item(0)).getNodeValue();

                    NodeList lonList = fstElmnt.getElementsByTagName("lng");
                    Element lonElement = (Element) lonList.item(0);
                    lonList = lonElement.getChildNodes();
                    String lng = ((Node) lonList.item(0)).getNodeValue();

                    MarkerInfo info = new MarkerInfo(name, Double.parseDouble(lat), Double.parseDouble(lng));
                    markerInfoList.add(info);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return markerInfoList;
        }

        @Override
        protected void onPostExecute(List<MarkerInfo> markerList) {

            for (MarkerInfo info : markerList) {
                mMap.addMarker(new MarkerOptions().position(new LatLng(info.lat, info.lon))
                        .title(info.name)
                        .icon(BitmapDescriptorFactory
                                .defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
            }

            if (markerList.size() > 0) {
                mMap.moveCamera(CameraUpdateFactory
                        .newLatLng(new LatLng(markerList.get(0).lat, markerList.get(0).lon)));
                mMap.animateCamera(CameraUpdateFactory.zoomTo(5));
            }
        }
    }

    public class MarkerInfo {
        double lat;
        double lon;
        String name;
        public MarkerInfo(String n, double la, double lo) {
            name = n;
            lat = la;
            lon = lo;
        }
    }

}

这是 Activity 的 res/layout/content_map_from_xml.xml 布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MapFromXML"
    tools:showIn="@layout/activity_map_from_xml">

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment" />

</RelativeLayout>

结果: