简体   繁体   English

Google Maps Android指向多边形

[英]Google Maps Android point in polygon

I creating a android app that uses google maps android api. 我创建了一个使用Google Maps Android API的Android应用。
This app need to to have a on click polygon function, but since it not available on google maps android api v2. 此应用需要具有点击多边形功能,但由于它在Google Maps Android API v2中不可用。 I did some research and found a work around for this function. 我做了一些研究,发现此功能可以解决。
What i ended up with is to check if a point is in a polygon method. 我最后要检查的是点是否在多边形方法中。
I'm using this library . 我正在使用这个图书馆 And it work pretty well if you create the bounds manually. 如果您手动创建边界,则效果很好。
If can create the bounds in a loop that would solve my problem. 如果可以在循环中创建边界,这将解决我的问题。
I get the polygon points from my database. 我从数据库中获取了多边形点。

Here is my MapFragment code: 这是我的MapFragment代码:

public class MapBlocksMapView extends Fragment {

    protected GoogleMap googleMap;
    protected LatLng latLng;
    protected Intent intent;
    protected String color, crops, block_code, tmp_user;

    public MapBlocksMapView() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ActionBar actionBar = getActivity().getActionBar();
        actionBar.setTitle("Block View");
        View rootView = inflater.inflate(R.layout.fragment_blocksmapview, container, false);

        if (googleMap== null) {
            googleMap= ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)).getMap();
        }

        Bundle bundle = getArguments();
        if (bundle != null) {
            block_code = bundle.getString("block_code");
            tmp_user = bundle.getString("user");
        }

        googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                checkpoint(latLng.latitude, latLng.longitude);
            }
        });
        return rootView;

    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        getdata(getActivity(), block_code);
        super.onActivityCreated(savedInstanceState);
    }

    private void checkpoint(double latitude, double longitude) {

        System.out.println(latitude +"," +longitude);
    }

    public void getdata(Context ctx, String block_code) {

        SQLHelper dbhelper = new SQLHelper(ctx);
        dbhelper.getReadableDatabase();

        JSONArray jsonArray = dbhelper.getSingleBlocks(block_code);

        try {
            for (int a = 0; a < jsonArray.length(); a++) {

                JSONObject jsonObject = new JSONObject(String.valueOf(jsonArray.getJSONObject(a)));
                JSONArray jsonArray1 = jsonObject.getJSONArray("b_points");
                if (jsonObject.getJSONArray("b_points").length() > 0) {
                    color = jsonObject.getString("b_color");
                    crops = jsonObject.getString("b_crop");
                    PolygonOptions rectOptions = new PolygonOptions();

                    for (int b = 0; b < jsonArray1.length(); b++) {
                        JSONArray jsonArray2 = jsonArray1.getJSONArray(b);

                        rectOptions.add(new LatLng(jsonArray2.getDouble(0), jsonArray2.getDouble(1)));


                        System.out.println(jsonArray2.get(0) + " / " + jsonArray2.get(1));

                    }
                    latLng = new LatLng(jsonArray1.getJSONArray(0).getDouble(0), jsonArray1.getJSONArray(0).getDouble(1));
                    rectOptions.strokeWidth(1).strokeColor(Color.parseColor(color)).fillColor(Color.parseColor(color));
                    googleMap.addPolygon(rectOptions);
                    CameraUpdate cameraPosition = CameraUpdateFactory.newLatLngZoom(latLng, 17);
                    googleMap.animateCamera(cameraPosition);

                } else {

                    Toast.makeText(getActivity(), "Error with the selected block", Toast.LENGTH_LONG).show();
                    closeFragment();
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        SupportMapFragment f = (SupportMapFragment) getFragmentManager()
                .findFragmentById(R.id.map);
        if (f != null)
            getFragmentManager().beginTransaction().remove(f).commit();
    }

    private void closeFragment() {
        getActivity().getFragmentManager().popBackStack();
    }

}

Here is the example code from the library: 这是库中的示例代码:

Polygon polygon = Polygon.Builder()
    .addVertex(new Point(1, 3))
    .addVertex(new Point(2, 8))
    .addVertex(new Point(5, 4))
    .addVertex(new Point(5, 9))
    .addVertex(new Point(7, 5))
    .addVertex(new Point(6, 1))
    .addVertex(new Point(3, 1))
    .build();

Point point = new Point(4.5f, 7);
boolean contains = polygon.contains(point);

If some have a other solution or suggestions would be helpful. 如果有人有其他解决方案或建议会有所帮助。
Thanks 谢谢

I also had the same problem but i haven't found a "good" solution for this issue. 我也有同样的问题,但是我没有找到解决此问题的“好”解决方案。

In the end i saved all polygons in a list and iterate through it with the click position. 最后,我将所有多边形保存在列表中,并通过单击位置对其进行迭代。 (but beware; maybe you have more than a single polygon at this position) (但是请注意;也许在这个位置上您有多个多边形)

well this that library isnt going to be much help because you have geographical positions and the library expects screen positions so you are going to be doing most of the work yourself really. 很好,图书馆不会有太大帮助,因为您具有地理位置,并且图书馆期望屏幕位置,这样您就可以真正完成大部分工作。

you need to take each latlng and convert them into screen points by getting the maps projection 您需要获取每个latlng并通过获取地图投影将其转换为屏幕点

Point point = googleMap.getProjection().toScreenLocation(myLatLngPoint);

then you can put that point into your library like you need when looping. 那么您可以在循环时根据需要将此点放入您的库中。 However I do not know what will be returned if the latlng you are using is not in the projection (ie. off the screen) so you will have to test that 但是我不知道如果您使用的latlng不在投影中(即不在屏幕上),将会返回什么,因此您必须测试一下

I manage to solve this after some digging around and found this code on github. 经过一些挖掘,我设法解决了这个问题,并在github上找到了这段代码。
I'm using this library now and it works like a charm. 我现在正在使用该 ,它的工作原理很吸引人。

My polygon points are stored like this in my database as string. 我的多边形点以字符串形式存储在数据库中。

[[3.65E-4,-1.1E-5],[-5.0E-6,3.54E-4],[-3.0E-6,-1.1E-4]]

Here is a example code 这是一个示例代码

protected double[] points;

public void getdata(){

    SQLHelper dbhelper = new SQLHelper(ctx);
    dbhelper.getReadableDatabase();

    String[] ls =dbhelper.getSingleBlocksPointsArray(block_code)
                .replaceAll("\\[", "")
                .replaceAll("\\]","")
                .split(",");
    points = new double[ls.length];
    for(int i=0;i<ls.length;i++)
    {

        points[i] = Double.parseDouble(ls[i]);
    }
}

in onCreateView i use this: 在onCreateView我使用此:

googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
    @Override
    public void onMapClick(LatLng latLng) {
        if(contains(new Coordinate(latLng.latitude,latLng.longitude), points)) {
            Toast.makeText(getActivity(),"True",Toast.LENGTH_SHORT).show();
        }else {
            Toast.makeText(getActivity(),"False",Toast.LENGTH_SHORT).show();
        }
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM