Osmdroid 空间查询 wfs支持

需求

遇到一个需求,需要在osmdroid地图中支持点击查询,查询所点击的地图图斑信息。

理论

地图服务geoserver支持WFS服务,用于地图查询

omdroid没有找到相关支持,所以手写了一个对wfs服务的调用调用分析

实现

自定义一个EventsOverlay类,继承自Overlay,用于接收地图的点击事件并分析点击的坐标位置

在获取的坐标位置生成一个小小的polygon进行图斑查询

手动拼接xml参数,返回结果拼接为polygon加载到地图上

代码

public class MainMapEventsOverlay extends Overlay {


    private static String TAG = "osmdroid-overlay";

    public Context context;
    public MapView mv;
    public String layer = null;
    public String srs;

    public int polygonFillColor;
    public int polygonOutlineWith;
    public int polygonOutlineColor;

    public JSONObject properties;

    private String par = "";
    private List<Polygon> listPolygon = new ArrayList<>();
    private Handler handler;

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e, MapView mv) {
        Projection proj = mv.getProjection();//获得投影对象
        GeoPoint gp = (GeoPoint) proj.fromPixels(((Float) e.getX()).intValue(), ((Float) e.getY()).intValue());//坐标转换

        Log.d(TAG, gp.toString());
        //没有图层时不查询
        if (layer == null) {
            return true;
        }
        par = "<GetFeature " +
                "xmlns=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.1.0\" outputFormat=\"application/json\" " +
                "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                "xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\">" +
                "<Query typeName=\"" + layer + "\" srsName=\"" + srs + "\" xmlns:sde=\"http://geoserver.sf.net\">" +
                "<Filter xmlns=\"http://www.opengis.net/ogc\">" +
                "<Intersects>" +
                "<PropertyName>geom</PropertyName>" +
                "<Polygon xmlns=\"http://www.opengis.net/gml\">" +
                "<exterior><LinearRing><posList srsDimension=\"2\">" +
                "" + gp.getLongitude() + " " + gp.getLatitude() + " " +
                "" + (gp.getLongitude() + 0.0000001) + " " + gp.getLatitude() + " " +
                "" + gp.getLongitude() + " " + (gp.getLatitude() + 0.0000001) + " " +
                "" + gp.getLongitude() + " " + gp.getLatitude() + "" +
                //"117.32810497283936 39.11452531814575 117.3310661315918 39.10838842391968 117.3391342163086 39.11684274673462 117.32810497283936 39.11452531814575" +
                "</posList>" +
                "</LinearRing>" +
                "</exterior>" +
                "</Polygon>" +
                "</Intersects></Filter></Query></GetFeature>";
        Log.d(TAG, par);

        for (int i = 0; i < listPolygon.size(); i++) {
            mv.getOverlays().remove(listPolygon.get(i));
        }
        listPolygon.clear();
        properties = null;
        MyThreadRunnable myThreadRunnable = new MyThreadRunnable();
        Thread thread = new Thread(myThreadRunnable);
        thread.start();
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 0:
                        for (int i = 0; i < listPolygon.size(); i++) {
                            mv.getOverlays().add(listPolygon.get(i));
                        }
                        mv.invalidate();//重绘地图
                        break;
                }
                super.handleMessage(msg);
            }
        };

        mv.invalidate();//重绘地图
        return true;
    }

    public void clear() {
        for (int i = 0; i < listPolygon.size(); i++) {
            mv.getOverlays().remove(listPolygon.get(i));
        }
        listPolygon.clear();
        mv.invalidate();//重绘地图
    }

    //创建线程方式二
    class MyThreadRunnable implements Runnable {

        @Override
        public void run() {
            try {


                URL url = new URL("https://www.hotworld.com.cn:1122/geoserver/wfs");

                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setConnectTimeout(30000);     //设置连接超时时间
                httpURLConnection.setDoInput(true);                  //打开输入流,以便从服务器获取数据
                httpURLConnection.setDoOutput(true);                 //打开输出流,以便向服务器提交数据
                httpURLConnection.setRequestMethod("POST");     //设置以Post方式提交数据
                httpURLConnection.setUseCaches(false);               //使用Post方式不能使用缓存
                //设置请求体的类型是文本类型
                httpURLConnection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
                //设置请求体的长度
                httpURLConnection.setRequestProperty("Content-Length", par.length() + "");
                //获得输出流,向服务器写入数据
                OutputStream outputStream = httpURLConnection.getOutputStream();
                outputStream.write(par.getBytes("UTF-8"));

                int response = httpURLConnection.getResponseCode();            //获得服务器的响应码
                if (response == HttpURLConnection.HTTP_OK) {
                    InputStream inptStream = httpURLConnection.getInputStream();
                    //return dealResponseResult(inptStream);                     //处理服务器的响应结果
                }

                StringBuffer buffer = new StringBuffer();
                // 从输入流读取返回内容
                InputStream inputStream = httpURLConnection.getInputStream();
                InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String str = null;
                while ((str = bufferedReader.readLine()) != null) {
                    buffer.append(str);
                }

                JSONTokener jsonTokener = new JSONTokener(buffer.toString());
                JSONObject jsonObject = (JSONObject) jsonTokener.nextValue();

                JSONArray features = jsonObject.getJSONArray("features");

                for (int i = 0; i < features.length(); i++) {
                    JSONObject feature = features.getJSONObject(i);

                    JSONObject geometry = feature.getJSONObject("geometry");
                    switch (geometry.getString("type")) {
                        case "MultiPolygon": {
                            Polygon polygon = new Polygon();
                            JSONArray coods = geometry.getJSONArray("coordinates").getJSONArray(0);
                            for (int holeIndex = 0; holeIndex < coods.length(); holeIndex++) {
                                List<GeoPoint> listPoints = new ArrayList<>();
                                for (int pointIndex = 0; pointIndex < coods.getJSONArray(holeIndex).length(); pointIndex++) {
                                    JSONArray point = coods.getJSONArray(holeIndex).getJSONArray(pointIndex);
                                    GeoPoint geoPoint = new GeoPoint(point.getDouble(1), point.getDouble(0));
                                    listPoints.add(geoPoint);
                                }
                                if (holeIndex == 0) {
                                    polygon.setPoints(listPoints);
                                } else {
                                    polygon.getHoles().add(listPoints);
                                }
                            }

                            polygon.getFillPaint().setColor(polygonFillColor);
                            polygon.getOutlinePaint().setColor(polygonOutlineColor);
                            polygon.setStrokeWidth(polygonOutlineWith);

                            listPolygon.add(polygon);
                        }
                        break;
                        case "Polygon": {

                            Polygon polygon = new Polygon();
                            JSONArray coods = geometry.getJSONArray("coordinates").getJSONArray(0);

                            List<GeoPoint> listPoints = new ArrayList<>();
                            for (int pointIndex = 0; pointIndex < coods.length(); pointIndex++) {
                                JSONArray point = coods.getJSONArray(pointIndex);
                                GeoPoint geoPoint = new GeoPoint(point.getDouble(1), point.getDouble(0));
                                listPoints.add(geoPoint);
                            }
                            polygon.setPoints(listPoints);

                            polygon.getFillPaint().setColor(polygonFillColor);
                            polygon.getOutlinePaint().setColor(polygonOutlineColor);
                            polygon.setStrokeWidth(polygonOutlineWith);

                            listPolygon.add(polygon);
                        }
                        break;
                    }

                    //获取属性信息与其他关联或者显示
                    properties = feature.getJSONObject("properties");

                }
                Message message = new Message();
                message.what = 0;
                handler.sendMessage(message);
                Log.d(TAG, buffer.toString());
            } catch (Exception ex) {
                Log.d(TAG, ex.toString());
            }
        }
    }

}
应用

        //点击查询图层
        mainMapEventsOverlay = new MainMapEventsOverlay();
        mainMapEventsOverlay.context = this;
        mainMapEventsOverlay.mv = mMapView;
        mainMapEventsOverlay.layer = "sde:ZFJCDL_XZDL";
        mainMapEventsOverlay.srs = "EPSG:4326";
        //渲染查询结果样式
        mainMapEventsOverlay.polygonFillColor = getColor(R.color.color_polygon_wtj);
        mainMapEventsOverlay.polygonOutlineWith = 1;
        mainMapEventsOverlay.polygonOutlineColor = getColor(R.color.color_polygon_line);

        mMapView.getOverlays().add(mainMapEventsOverlay);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值