leaflets学习——geoJSON图层

关注公众号,分享GIS知识、ArcGIS教程、SCI论文与科研日常等

提供实现从后端数据库postGIS提取矢量数据到前端,以及前端的矢量数据传到后端进行空间关系查询的思路。
这里数据的传输形式即为geoJSON格式。什么是geoJSON

1.前端leaflets-geoJSON图层

首先假定已经获取一个geoJSON对象,本质上是JSON格式:

var geojsonFeature = {
    "type": "Feature",
    "properties": {
        "name": "Coors Field",
        "amenity": "Baseball Stadium",
        "popupContent": "This is where the Rockies play!"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [-104.99404, 39.75621]
    }
};

两种方式将它添加到地图:

L.geoJSON(geojsonFeature).addTo(map);

或者

var myLayer = L.geoJSON().addTo(map);
myLayer.addData(geojsonFeature);

其次还可以用geoJSON()的第二个参数options定义样式:

L.geoJSON(geojsonFeature, {
    style: {
    "color": "#ff7800",
    "weight": 5,
    "opacity": 0.65
	}
}).addTo(map);

进一步,使用onEachFeature属性,在加入图层之前对feature进行调用处理,如绑定泡泡:

function onEachFeature(feature, layer) {
    // does this feature have a property named popupContent?
    if (feature.properties && feature.properties.popupContent) {
        layer.bindPopup(feature.properties.popupContent);
    }
}

L.geoJSON(geojsonFeature, {
    style: {
    "color": "#ff7800",
    "weight": 5,
    "opacity": 0.65
	},
	onEachFeature:onEachFeature
}).addTo(map);

2. 后端postGIS数据库geoJSON的使用

a. 从PostGIS数据库获取geoJSON格式。

从数据库查询到前端展示的过程。

假设数据库中有个简单的关系表mytable,它的元数据如下:

列名值类型
idnumber
nametext
geomgeometry

geom列存储的为几何信息。类型为geometry。后端Java连接数据库并查询该关系表。
查询SQL语句:

SELECT name,ST_AsGeoJSON(geom)::jsonb geomjson FROM mytable

ST_AsGeoJSON()为postgres的内置函数,名字很容易看出来,就是获取geometry的geoJSON格式。Java中,获取的结果为string,再处理一下,转为JSONObject格式。

JSONObject jsonObject =new JSONObject();

//大多数情况下为feaurecollection
ArrayList<JSONObject> featureslist = new ArrayList<JSONObject>();

while (resultSet.next()) {
    JSONObject featureJsonObject = new JSONObject();


    JSONObject featurePrpoJsonObject = new JSONObject();
    String geometryJsonObjectstr=null;
    JSONObject geometryJsonObject = null;


    ResultSetMetaData schema = resultSet.getMetaData();
    int columnCount = schema.getColumnCount();
    int type;
    String columnName;

    for (int i=1;i<=columnCount;i++){
        columnName = schema.getColumnName(i);        
        if(columnName.equals("name")){
            featurePrpoJsonObject.put("name",resultSet.getString(i));
        }
        if (columnName.equals("geomjson")){
            geometryJsonObjectstr =  resultSet.getString(i);
            //这里读取的查询结果,读成String类型,下一步再转为JSONObject
            geometryJsonObject = new JSONObject(geometryJsonObjectstr);
        }
    }
    featureJsonObject.put("type","Feature");
    featureJsonObject.put("properties",featurePrpoJsonObject);
    featureJsonObject.put("geometry",geometryJsonObject);


    featureslist.add(featureJsonObject);
}

JSONObject[] features = list2jsonarr(featureslist);
jsonObject.put("features",features);
jsonObject.put("type","FeatrueCollection");
JsonContent =jsonObject.toString();
//response JsonContent到前端
private JSONObject[] list2jsonarr(ArrayList<JSONObject> featureslist){
        JSONObject[] features=new JSONObject[featureslist.size()];
        for (int i=0;i<featureslist.size();i++)
        {
            features[i]=featureslist.get(i);
        }
        return  features;
    }
b. geoJSON格式数据转为Post数据库的geom并执行空间关系查询

前端提交请求到后端数据库使用请求数据的过程。一般webGIS都需要处理空间查询工作。比如用户想要查询在河南省范围内的要素。

PostGIS数据库的内置函数ST_GeomFromGeoJSON()可以将geoJSON格式的数据或者geoJSON格式的字符串转为geometry。

geometry ST_GeomFromGeoJSON(text geomjson);
geometry ST_GeomFromGeoJSON(json geomjson);
geometry ST_GeomFromGeoJSON(jsonb geomjson);

例如进行下面的空间查询:

SELECT ST_AsGeoJSON(geom)::jsonb geomjson FROM mytable WHERE ST_Within(ST_SetSRID(geom,4326), ST_GeomFromGeoJSON('{"type":"Polygon","coordinates":[[[112.502324,44.543145],[105.558485,40.230489],[111.00808,36.723943],[117.336643,36.582973],[123.357567,45.072967],[116.765314,46.361079],[112.502324,44.543145]]]}'))

首先将geoJSON转化为geometry,在进行空间查询,这里的geojson不包含属性字段。只包含type和coordinates。因此如果是featurecollection的GeoJSON需要进一步处理。

{	"type":"Polygon",
	"coordinates":[[[112.502324,44.543145],[105.558485,40.230489],[111.00808,36.723943],[117.336643,36.582973],[123.357567,45.072967],[116.765314,46.361079],[112.502324,44.543145]]]
}

拓展,postgis空间几何关系函数

ST_Distance(geometry, geometry)
返回两个几何对象的距离(笛卡儿距离),不使用索引。 
 
ST_DWithid(geometry, geometry, float)
如果一个几何对象(geometry)在另一个几何对象描述的距离(float)内,返回TRUE。如果有索引,会用到索引。

ST_Equals(geometry, geometry)
如果两个空间对象相等,则返回TRUE。用这个函数比用“=”更好,例如:
equals(LINESTRING(0 0, 10 10),LINESTRING(0 0, 5 5, 10 10)) 返回 TRUEST_Disjoint(geometry, geometry)
如果两个对象不相连,则返回TRUE。不要使用GeometryCollection作为参数。

ST_Intersects(geometry, geometry)
判断两个几何空间数据是否相交,如果相交返回true,不要使用GeometryCollection作为参数。
Intersects(g1, g2 )> Not (Disjoint(g1, g2 ))
不使用索引可以用_ST_Intersects.

ST_Touches(geometry, geometry)
如果两个几何空间对象存在接触,则返回TRUE。不要使用GeometryCollection作为参数。
a.Touches(b) -> (I(a) intersection I(b) = {empty set} ) and (a intersection b) not empty
不使用索引可以用_ST_Touches.

ST_Crosses(geometry, geometry)
如果两个几何空间对象存在交叉,则返回TRUE。不要使用GeometryCollection作为参数。
不使用索引可以用_ST_Crosses.

ST_Within(geometry A, geometry B)
如果几何空间对象A存在空间对象B,则返回TRUE,不要使用GeometryCollection作为参数。
不使用索引可以用_ST_Within

ST_Overlaps(geometry, geometry)
如果两个几何空间数据存在交迭,则返回 TRUE,不要使用GeometryCollection作为参数。
不使用索引可以用_ST_Overlaps.

ST_Contains(geometry A, geometry B)
如果几何空间对象A包含空间对象B,则返回 TRUE,不要使用GeometryCollection作为参数。
这个函数类似于ST_Within(geometry B, geometry A)
不使用索引可以用_ST_Contains.

ST_Covers(geometry A, geometry B)
如果几何空间对象B中的所有点都在空间对象A,则返回 TRUE。
不要使用GeometryCollection作为参数。
不使用索引可以用_ST_Covers.

ST_CoveredBy(geometry A, geometry B)
如果几何空间对象A中的所有点都在空间对象B,则返回 TRUE

3. 前后端传输—AJAX

下面函数提供POST提交请求,进行空间查询,并将返回结果添加到map。查询条件包括数据集名称、特定区域内、起始时间等信息。与地理空间数据云的筛选数据差不多。
在这里插入图片描述

function fun(){
	postdata={
	                //请求内容,根据后端框架自己定义
	                request:"getfeature",
	                requestContent:"measuredssm",
	                outputFormat:"application/json",
	                geomJson:JSON.stringify(shapefileLayer.toGeoJSON().features[0].geometry),
	                starttime:"2020-06-15",
	                endtime:"2020-07-15",
	                typeName:datasetname
	            };	
	$.post({	            
				url:"/cai/WebFeatureServlet",
	            data:postdata,
	            dataType:"json",
	            success:function (res) {
	                geojsonlayer = L.geoJSON(res.features,
	                    {
	                        onEachFeature:onEachFeature2
	                    }
	                ).addTo(leafletmap);
	            },
	            error:function (err) {
	                window.alert(err);
	            }
	        });
    }
  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
使用leaflets和天地图时,如果出现地图错乱的情况,可能是由于以下几个原因引起的: 1. 引入天地图的WMTS时,可能在URL链接中没有正确设置参数或者URL链接错误。请确保引入的矢量地图和标注地图的URL链接正确,并且提供了合适的天地图服务的key。 2. leaflets的初始化设置可能有问题。请检查地图的中心点、缩放级别、投影方式等是否正确设置。 3. leaflets和天地图的版本兼容性问题。请确保使用的leaflets和天地图的版本是兼容的,可以尝试更新至最新版本或者降级至兼容的版本。 4. 其他原因,例如网络连接问题或者浏览器缓存问题,也可能导致地图错乱。可以尝试清除浏览器缓存或者切换至其他网络环境来解决。 综上所述,如果leaflets天地图出现错乱,需要检查天地图的URL链接、leaflets的初始化设置、版本兼容性以及其他可能的问题,以确定并解决具体的原因。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [leaflets地图插件](https://blog.csdn.net/lydia_love/article/details/104354794)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [leaflet 加载天地图](https://blog.csdn.net/xiaofan_queen/article/details/120285520)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cshgiser

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值