【问题标题】:How to show coordinates-markers on Android App with Google Maps from XML file如何使用来自 XML 文件的 Google 地图在 Android 应用上显示坐标标记
【发布时间】:2017-04-05 15:26:11
【问题描述】:

我有一个 xml 文件,其中包含一些位置及其坐标。我想在谷歌地图上的我的安卓应用程序上显示这些地方作为标记。我已经加载了地图。 我怎么能这样做?任何帮助都会非常感激,即使有人可以从理论上解释它,因为我似乎无法理解它的概念。有人可以帮忙吗?

xml 文件示例(placesp.xml):

<placesp>
<placep>
  <place_id>1</place_id>
  <name>Place1</name>
  <description>Place description 1</description>
  <coordinates>;40.430224;21.559570</coordinates>
</placep>
<placep>
  <place_id>2</place_id>
  <name>Place2</name>
  <description>Place description 2</description>
  <coordinates>;40.423324;21.062439</coordinates>
</placep>
<placep>
  <place_id>3</place_id>
  <name>Place3</name>
  <description>Place description 3</description>
  <coordinates>;40.266952;21.238220</coordinates>
</placep>
</placesp>

【问题讨论】:

    标签: java android xml google-maps


    【解决方案1】:

    也许您可以使用 HashMap 来保存数据。 您只需像这样创建一个新类:

    public class Coordinates {
    public static final HashMap<String, LatLng> COORDINATES = new HashMap<String, LatLng>();
    static {
    
        // Place1
        COORDINATES.put("Place1", new LatLng(40.430224;21.559570));
    }
    

    }

    您可以像这样访问 hashmap 存储的数据:

                    locationLatLng = new LatLng(Coordinates.COORDINATES.get("Place1").latitude,Coordinates.COORDINATES.get("Place1").longitude); 
    

    然后在加载地图的类中使用这一行来添加标记:

    map.addMarker(new MarkerOptions().position(locationLatLng));
    

    我不太确定如何从 xml 文件中访问数据,但理论上逻辑是相同的。你必须得到一个 LatLng 坐标来告诉 addMarker 方法将标记放在哪里,实际上就是这样。希望能帮到你。

    【讨论】:

    • 您好,感谢您的回答!有没有办法从 xml 文件中获取地点的信息?所以如果我改变了内容,地图上的标记也会改变吗?
    • developer.android.com/guide/topics/resources/… 看看这个。在 values 文件夹中有一个默认的 strings.xml 文件,可以在代码中通过 getString(R.string.NAME) 访问它...也许您可以将坐标放在字符串中,然后将它们转换为 LatLng。显然你不能根据这个访问自定义 xml 文件的数据:stackoverflow.com/questions/15152933/…
    【解决方案2】:

    首先,您需要创建一个模型类来保存每个地点的信息。我在下面为您提供一个示例:Place.class

    public class Place {
    private int placeId;
    private String placeName;
    private String placeDescription;
    private double placeLongitude;
    private double placeLatitude;
    
    public Place() {
        super();
    }
    
    public int getPlaceId() {
        return placeId;
    }
    
    public void setPlaceId(final int placeId) {
        this.placeId = placeId;
    }
    
    public String getPlaceName() {
        return placeName;
    }
    
    public void setPlaceName(final String placeName) {
        this.placeName = placeName;
    }
    
    public String getPlaceDescription() {
        return placeDescription;
    }
    
    public void setPlaceDescription(final String placeDescription) {
        this.placeDescription = placeDescription;
    }
    
    public double getPlaceLongitude() {
        return placeLongitude;
    }
    
    public void setPlaceLongitude(final double placeLongitude) {
        this.placeLongitude = placeLongitude;
    }
    
    public double getPlaceLatitude() {
        return placeLatitude;
    }
    
    public void setPlaceLatitude(final double placeLatitude) {
        this.placeLatitude = placeLatitude;
    }
    }
    

    接下来,您将需要一个 XML 解析器类来检索 XML 数据到 Place 类型列表。您可以使用以下示例:PlaceXmlParser.class

    public class PlaceXmlParser {
    private static final String TAG = PlaceXmlParser.class.getSimpleName();
    private static final String PLACE_ID = "place_id";
    private static final String PLACE_NAME = "name";
    private static final String PLACE_DESCRIPTION = "description";
    private static final String PLACE_COORDINATES = "coordinates";
    
    public PlaceXmlParser() {
        super();
    }
    
    public List<Place> parsePlacesXml(final InputStream xmlStream) {
        Place place = null;
        final List<Place> placeList = new ArrayList<>();
        try {
            final XmlPullParserFactory xmlFactoryObject = XmlPullParserFactory.newInstance();
            final XmlPullParser parser = xmlFactoryObject.newPullParser();
            parser.setInput(xmlStream, null);
            int event = parser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT) {
                if (event == XmlPullParser.START_TAG) {
                    final String name = parser.getName();
                    switch (name) {
                        case PLACE_ID:
                            place = new Place();
                            setPlaceId(parser, place);
                            break;
                        case PLACE_NAME:
                            setPlaceName(parser, place);
                            break;
                        case PLACE_DESCRIPTION:
                            setPlaceDescription(parser, place);
                            break;
                        case PLACE_COORDINATES:
                            setPlaceLatLong(parser, place);
                            placeList.add(place);
                            break;
                    }
                }
                event = parser.next();
            }
        } catch (final XmlPullParserException e) {
            Log.e(TAG, e.toString());
        } catch (final IOException e) {
            Log.e(TAG, e.toString());
        }
        return placeList;
    }
    
    private boolean areValidArgs(final XmlPullParser parser, final Place place) {
        return null != parser && null != place;
    }
    
    private void setPlaceId(final XmlPullParser parser, final Place place) {
        if (areValidArgs(parser, place)) {
            final String placeId = getTagValue(parser);
            place.setPlaceId(Integer.parseInt(placeId));
        }
    }
    
    private void setPlaceName(final XmlPullParser parser, final Place place) {
        if (areValidArgs(parser, place)) {
            final String placeName = getTagValue(parser);
            place.setPlaceName(placeName);
        }
    }
    
    private void setPlaceDescription(final XmlPullParser parser, final Place place) {
        if (areValidArgs(parser, place)) {
            final String placeDescription = getTagValue(parser);
            place.setPlaceDescription(placeDescription);
        }
    }
    
    private void setPlaceLatLong(final XmlPullParser parser, final Place place) {
        if (areValidArgs(parser, place)) {
            final String[] latLong = getTagValue(parser).split(";");
            if (3 == latLong.length) {
                place.setPlaceLatitude(Double.parseDouble(latLong[1]));
                place.setPlaceLongitude(Double.parseDouble(latLong[2]));
            }
        }
    }
    
    private String getTagValue(final XmlPullParser parser) {
        String result = "";
        try {
            if (parser.next() == XmlPullParser.TEXT) {
                result = parser.getText();
                parser.nextTag();
            }
        } catch (final XmlPullParserException e) {
            Log.e(TAG, e.toString());
        } catch (final IOException e) {
            Log.e(TAG, e.toString());
        }
        return result;
    }
    
    }
    

    最后,在你的谷歌地图的活动中,实现 OnMapReadyCallback 接口,重写 onMapReady 方法并向谷歌地图添加地点标记:MapActivity.class

    public class MapActivity extends FragmentActivity implements OnMapReadyCallback {
    private GoogleMap mMap;
    private List<Place> placeList;
    
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        this.placeList = getPlaceList();
    }
    
    @Override
    public void onMapReady(final GoogleMap googleMap) {
        this.mMap = googleMap;
        addPlaceListMarkersToGoogleMap();
    }
    
    private void addPlaceListMarkersToGoogleMap() {
        for (final Place place : this.placeList) {
            final LatLong latLong = new LatLong(place.getPlaceLatitude(), place.getPlaceLongitude());
            this.mMap.addMarker(new MarkerOptions().position(latLong).title(place.getPlaceName()));
        }
    }
    
    private List<Place> getPlaceList() {
        final String xmlString = "<placesp>" +
                "<placep>" +
                "  <place_id>1</place_id>" +
                "  <name>Place1</name>" +
                "  <description>Place description 1</description>" +
                "  <coordinates>;40.430224;21.559570</coordinates>" +
                "</placep>" +
                "<placep>" +
                "  <place_id>2</place_id>" +
                "  <name>Place2</name>" +
                "  <description>Place description 2</description>" +
                "  <coordinates>;40.423324;21.062439</coordinates>" +
                "</placep>" +
                "<placep>" +
                "  <place_id>3</place_id>" +
                "  <name>Place3</name>" +
                "  <description>Place description 3</description>" +
                "  <coordinates>;40.266952;21.238220</coordinates>" +
                "</placep>" +
                "</placesp>";
        final InputStream xmlStream = getXmlStream(xmlString);
        final PlaceXmlParser parser = new PlaceXmlParser();
        return parser.parsePlacesXml(xmlStream);
    }
    
    private InputStream getXmlStream(final String xmlString) {
        InputStream xmlStream = null;
        try {
            xmlStream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
        } catch (final UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return xmlStream;
    }
    }
    

    提供的代码适用于给定的 XML 示例,请注意可能的异常并处理它。希望对您有所帮助!

    【讨论】:

    • 嘿,非常感谢您花时间回答这个问题!我正在尝试在我的项目中实现这一点,我有一个问题,也许是一个愚蠢的问题。在 MapActivity.class 的代码中,您编写了final String xmlString = "&lt;placesp&gt;" + "&lt;placep&gt;" + " &lt;place_id&gt;1&lt;/place_id&gt;" + ..; 等。为什么会这样?我不能以某种方式插入 placesp.xml 文件吗?那么如果文件的内容发生变化,地图会显示不同的标记?
    • 首先,是的,您可以从 XML 文件而不是硬编码字符串中读取数据,并且提供的示例也可以。其次,是的,如果您更改文件内容(信息而不是格式),地图将显示不同的标记
    • 我该怎么做?我应该输入 xml 文件的名称而不是硬编码的字符串吗?像 ..="placesp.xml" 之类的东西?或者我需要更多的代码?
    • 我为您提供了一个很好的答案,效果非常好。你没有验证我的回答,你想让我继续做你的工作吗?
    • 态度怎么样?我问这个问题是因为我想知道如何从 xml 文件中获取数据并将它们显示到地图上。我在你的答案中问你的是我想通过提问来知道的。我知道如何在地图上显示一个地方,我不知道如何从 xml 文件中获取数据,然后将它们显示到地图上。因此,尽管您的答案可能非常有效,但它并没有回答我的问题。再次感谢您的宝贵时间。
    猜你喜欢
    • 1970-01-01
    • 2020-09-17
    • 2014-08-23
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 2018-04-17
    相关资源
    最近更新 更多