与方向谷歌地图集群 [英] Google map cluster with direction

查看:304
本文介绍了与方向谷歌地图集群的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个谷歌地图图书馆展现在集群的倍数标记。

We have a Google map library to show multiples markers in cluster.

我有两个问题:

集群是象下面这样:

我给你举例:来回的国家印度,我有保存不同的方向在我的分贝

i will give you examples : fro country India i have save different directions in my db.

喜欢

艾哈迈达巴德德里

德里到阿格拉

艾哈迈达巴德到孟买

jaypur德里

我要展现的上述指示集群取决于缩放级别, 当用户放大谷歌地图,而不是集群有多个方向显示在谷歌地图。

I have to show cluster of above directions depend on zoom level, when user zoom Google map, instead of clusters there is multiple directions showing on Google Map.

我想知道,如果它的可能吗?如果是的话怎么办?

I want to know if its possible? If yes then how?

推荐答案

您可以通过使用方向API实现自己的目标。你提供的出发点和结束点(也可以是地方的任纬度/经度或名称)。另一个必需字段行驶模式(默认驱动)。

You can achieve your goal by using the Directions API. You supply the starting point and the ending point (it can be either lat/lon or name of the place). Another required field is the traveling mode (driving by default).

现在的路线返回的可以转化为多段线,然后绘制在地图上的顶点。 这个答案确实是pretty的很好,我会用它的code。

Now the Directions return the vertexes which can be transformed to a polyline and then drawn on the map. This answer does that pretty well and I'll be using it's code.

package com.example.simon.maps;

import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Document;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import android.graphics.Color;
import android.os.Bundle;
import android.os.StrictMode;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.util.SparseArray;

/**
 * Created by Simon on 2014 Jul 25.
 */

public class MainActivity extends FragmentActivity {

    final static String TAG = "MainActivity";
    GoogleMap mMap;
    GMapV2Direction md;
    int mZoomLevel;
    final float STARTING_ZOOM = 5.0f;
    // List of polylines for each zoom level
    SparseArray<List<Polyline>> mPolylines = new SparseArray<List<Polyline>>();

    public class direction {
        String start, end;
        int zoomLevel;

        direction(String pStart, String pEnd, int pZoomLevel) {
            start = pStart;
            end = pEnd;
            zoomLevel = pZoomLevel;
        }
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (android.os.Build.VERSION.SDK_INT > 9) {
            StrictMode.ThreadPolicy p = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(p);
        }

        md = new GMapV2Direction();
        mMap = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();

        List<direction> directions = new ArrayList<direction>();
        directions.add(new direction("Ahmedabad,Gujarat,India", "delhi,India", 4));
        directions.add(new direction("Ahmedabad,Gujarat,India","Bombay,Maharashtra,India", 4));
        directions.add(new direction("Jeypore,Odisha,India", "delhi,India", 5));
        for (MainActivity.direction direction : directions) {
            // Query
            Document doc = md.getDocument(direction.start, direction.end);
            // Parse the xml
            if (doc == null) {
                Log.e(TAG, "Failed to get the route from " + direction.start
                        + " to " + direction.end);
                continue;
            }
            // Get points
            ArrayList<LatLng> directionPoint = md.getDirection(doc);
            // Convert vertexes to a polyline
            PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED);
            for (LatLng aDirectionPoint : directionPoint) {
                rectLine.add(aDirectionPoint);
            }
            // Add poly to the map
            addPolyline(rectLine, direction.zoomLevel);
        }
        // Get the starting point of the first direction
        LatLng start = mPolylines.valueAt(0).get(0).getPoints().get(0);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(start, STARTING_ZOOM), 1000, null);
        // Set the initial zoom level and show the necessary polylines
        mZoomLevel = (int) STARTING_ZOOM;
        initPolylines(mZoomLevel);

        // Listen for the camera zoom level changes
        mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
                // Note that because we are casting the zoomLevel to int,
                // it will be considered as changed only when it reaches
                // a new integer when rounded (e.g. 5.0, 6.0 etc.)
                int newZoomLevel = (int) cameraPosition.zoom;
                if (newZoomLevel != mZoomLevel) {
                    Log.d(TAG, "New zoom level: " + newZoomLevel);
                    // Loop all the changed zoom levels
                    // E.g. zoomed-out from 15 to 13, then hide [14, 15]
                    if (newZoomLevel < mZoomLevel) { // Zoomed out
                        for (int i=1; i<=mZoomLevel-newZoomLevel; i++)
                            hidePolylines(mPolylines.get(newZoomLevel+i));
                    } else { // Zoomed-in
                        for (int i=1; i<=newZoomLevel-mZoomLevel; i++)
                            showPolylines(mPolylines.get(mZoomLevel + i));
                    }
                    mZoomLevel = newZoomLevel;
                }
            }
        });
    }

    private void addPolyline(PolylineOptions polyOpts, int zoomLevel) {
        List<Polyline> polylines = mPolylines.get(zoomLevel);
        // Create polyline list for this zoom level, if it still doesn't exist
        if (polylines == null) {
            polylines = new ArrayList<Polyline>();
            mPolylines.put(zoomLevel, polylines);
        }
        // Append a new item to this poly list
        Polyline polyline = mMap.addPolyline(polyOpts);
        polyline.setVisible(false);
        polylines.add(polyline);
    }

    private void initPolylines(int zoomLevel) {
        for(int i=0; i<mPolylines.size(); i++) {
            // Loop until zoom level is reached
            if  (mPolylines.keyAt(i) > zoomLevel) break;

            showPolylines(mPolylines.get(mPolylines.keyAt(i)));
        }
    }

    private void showPolylines(List<Polyline> polylines) {
        if (polylines != null)
            for (Polyline polyline : polylines) polyline.setVisible(true);
    }

    private void hidePolylines(List<Polyline> polylines) {
        if (polylines != null)
            for (Polyline polyline : polylines) polyline.setVisible(false);
    }

}

这code增加了折线到一个SparseArray持有的折线每个缩放级别。所有polies默认情况下隐藏的,只有显露在达到一个特定的缩放级别(也为 initPolylines )。

This code adds the polylines to a SparseArray which holds the polylines for each zoom level. All polies are hidden by default and are revealed only when a specific zoom level is reached (also at initPolylines).

有几件事情需要注意:

  1. 由于变焦可以通过几级一下子我们循环每个级别的隐藏/显示特定的方向改变。
  2. 的位置名称必须是precise 或他们将不会被发现,你可能会收到一束在code错误(我只加了日志。 E)
  3. 如果你想创建标记的,假设的起点和方向的终点,你可以使用下面的code得到的坐标:

  1. Because the zoom can change by a few levels at once we loop each level to hide/show specific directions.
  2. The location names have to be precise or they won't be found and you might receive a bunch of errors in the code (I've only added a Log.e)
  3. If you want to create markers at, let's say the starting and the ending point of the direction, you can use the following code to get the coordinates:

List<LatLng> points = mPolylines.valueAt(0).get(0).getPoints();
LatLng start = points.get(0);
LatLng end = points.get(points.size()-1);

  • 标记可以被添加/特定缩放级别,就像它在这里做的多段线删除。
  • 和这里的XML解析器(GMapV2Direction)的code:

    And here's the code of the xml parser (GMapV2Direction):

    package com.example.simon.maps;
    
    import java.io.InputStream;
    import java.util.ArrayList;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.protocol.BasicHttpContext;
    import org.apache.http.protocol.HttpContext;
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import com.google.android.gms.maps.model.LatLng;
    
    public class GMapV2Direction {
    
        public GMapV2Direction() { }
    
        public Document getDocument(String start, String end) {
            String url = "http://maps.googleapis.com/maps/api/directions/xml?"
                    + "origin="+start+"&destination="+end+"&units=metric&mode=driving";
            try {
                HttpClient httpClient = new DefaultHttpClient();
                HttpContext localContext = new BasicHttpContext();
                HttpPost httpPost = new HttpPost(url);
                HttpResponse response = httpClient.execute(httpPost, localContext);
                InputStream in = response.getEntity().getContent();
                DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                return builder.parse(in);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public ArrayList<LatLng> getDirection (Document doc) {
            NodeList nl1, nl2, nl3;
            ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
            nl1 = doc.getElementsByTagName("step");
            if (nl1.getLength() > 0) {
                for (int i = 0; i < nl1.getLength(); i++) {
                    Node node1 = nl1.item(i);
                    nl2 = node1.getChildNodes();
    
                    Node locationNode = nl2.item(getNodeIndex(nl2, "start_location"));
                    nl3 = locationNode.getChildNodes();
                    Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
                    double lat = Double.parseDouble(latNode.getTextContent());
                    Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                    double lng = Double.parseDouble(lngNode.getTextContent());
                    listGeopoints.add(new LatLng(lat, lng));
    
                    locationNode = nl2.item(getNodeIndex(nl2, "polyline"));
                    nl3 = locationNode.getChildNodes();
                    latNode = nl3.item(getNodeIndex(nl3, "points"));
                    ArrayList<LatLng> arr = decodePoly(latNode.getTextContent());
                    for (LatLng anArr : arr) {
                        listGeopoints.add(new LatLng(anArr.latitude, anArr.longitude));
                    }
    
                    locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
                    nl3 = locationNode.getChildNodes();
                    latNode = nl3.item(getNodeIndex(nl3, "lat"));
                    lat = Double.parseDouble(latNode.getTextContent());
                    lngNode = nl3.item(getNodeIndex(nl3, "lng"));
                    lng = Double.parseDouble(lngNode.getTextContent());
                    listGeopoints.add(new LatLng(lat, lng));
                }
            }
    
            return listGeopoints;
        }
    
        private int getNodeIndex(NodeList nl, String nodename) {
            for(int i = 0 ; i < nl.getLength() ; i++) {
                if(nl.item(i).getNodeName().equals(nodename))
                    return i;
            }
            return -1;
        }
    
        private ArrayList<LatLng> decodePoly(String encoded) {
            ArrayList<LatLng> poly = new ArrayList<LatLng>();
            int index = 0, len = encoded.length();
            int lat = 0, lng = 0;
            while (index < len) {
                int b, shift = 0, result = 0;
                do {
                    b = encoded.charAt(index++) - 63;
                    result |= (b & 0x1f) << shift;
                    shift += 5;
                } while (b >= 0x20);
                int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
                lat += dlat;
                shift = 0;
                result = 0;
                do {
                    b = encoded.charAt(index++) - 63;
                    result |= (b & 0x1f) << shift;
                    shift += 5;
                } while (b >= 0x20);
                int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
                lng += dlng;
    
                LatLng position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
                poly.add(position);
            }
            return poly;
        }
    }
    

    最后的一些注意事项:

    Some final notes:

    • 如果您已经有很多方向内侧加载它们 initPolylines showPolylines 和卸载它们 hidePolylines
    • 如果你想显示在地图上的方向是不变的,最好的办法是使用瓷砖与特定的缩放级别的折线。一个很好的免费工具,那就是 Maperitive ,它可以在瓷砖出口到尽可能多的缩放级别,只要你想。然后,你将存储的瓷砖在线和使用UrlTileProvider来显示它们在地图上。
    • If you've a lot of directions load them inside initPolylines and showPolylines and unload them in hidePolylines
    • If the directions you want to show on the map are constant, the best way would be to use tiles with polylines on specific zoom levels. A good free tool for that is Maperitive, it can export the tiles to as many zoom levels as you want. Then you would store the tiles online and use UrlTileProvider to display them on your map.

    这篇关于与方向谷歌地图集群的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆