简体   繁体   English

使用 Leaflet 在 GeometryCollection 类型中设置几何样式

[英]Set style for geometries in GeometryCollection type with Leaflet

I work on web based GIS system where customers have many layers (sometimes overlaps each other) they can add/edit/delete elements geometry or properties from some layer.我在基于 Web 的 GIS 系统上工作,其中客户有很多层(有时相互重叠),他们可以从某个层添加/编辑/删除元素几何或属性。 In back-end the system is 100% restful api based and have heavy administration structure.在后端,系统是 100% 基于 RESTful api 的,并且具有繁重的管理结构。 Each layer have 4 tables (1 for properties, 1 for geometry, 1 for dynamic data and 1 relation table with other service attributes like custom type, date create, date edit, active, etc.) The layers is saved in different servers.每个图层有 4 个表(1 个用于属性,1 个用于几何,1 个用于动态数据和 1 个具有其他服务属性(如自定义类型、日期创建、日期编辑、活动等)的关系表)。图层保存在不同的服务器中。 DB is MySQL and PostgreSQL(PostGIS) and MySQL. DB 是 MySQL 和 PostgreSQL(PostGIS) 和 MySQL。 When we start this project we agree to allow only one type geometry in layer like point, polygon etc. but now i must create a functionality where clients can work with many types in 1 layer but this is not a problem.当我们开始这个项目时,我们同意在层中只允许一种类型的几何图形,如点、多边形等。但现在我必须创建一个功能,客户端可以在 1 层中使用多种类型,但这不是问题。 The real problem is that the system must supports GeometryCollection type and must style each geometries in GeometryCollection.真正的问题是系统必须支持 GeometryCollection 类型并且必须在 GeometryCollection 中设置每个几何图形的样式。

When i use function like this:当我使用这样的功能时:

layer.setStyle(some_style_object);

This work for Polygons and MultiPolygons, but then i try to use function to style the icon like this:这适用于多边形和 MultiPolygons,但随后我尝试使用函数来设置图标样式,如下所示:

layer.setIcon(some_style_object);

This give me a error like this:这给了我这样的错误:

Uncaught TypeError: layer.setIcon is not a function at Object.onEachFeature

The GeometryCollection look like this: GeometryCollection 看起来像这样:

{
"type":"Feature","properties":{
"id":"143","DistrictID":"12145","DistrictName":"ЗОНА Б-5","DistrictTypeID":"2","SubcontractorDescription":null,"DispEmpID":"23974","SubstDispEmpID":"21976","CompanyRepEmpID":"22487","TitulCourierEmpID":"20750","TitulCourierEmpName":null,"NearByOfficeID":null,"AreaOfficeID":"110","OfficeID":"142","OfficeName":"BOZHURISHTE","DispEmpName":null,"label":null,"notes":null,"style":"#FFFF00","worker_elements":"a:2:{i:36;a:3:{i:0;i:100036000004686;i:1;i:100036000004688;i:2;i:100036000004689;}i:43;a:3:{i:3;i:100043000000154;i:4;i:100043000000160;i:5;i:100043000000187;}}","attributes_id":"143","geometry_id":"143","type_id":"64","active":"1","createdID":"2","editedID":null,"DateFrom":"2020-09-18 18:08:17","DateTo":null,"BrickID":"100042000000143","dinamic_attributes":{"id":null,"PICKUP_WAYBILLS_COUNT":null,"PICKUP_VISITS_COUNT":null,"PICKUP_COURIERPAYMENT":null,"PICKUP_TOTALINCOME":null,"PICKUP_CALCULATIONWEIGHT":null,"DELIVERY_WAYBILLS_COUNT":null,"DELIVERY_VISITS_COUNT":null,"DELIVERY_COURIERPAYMENT":null,"DELIVERY_TOTALINCOME":null,"DELIVERY_CALCULATIONWEIGHT":null},"layer_id":"42","custom_label":null},
"geometry":{
"type":"GeometryCollection",
"geometries":[
{"type":"Point","coordinates":[23.30802,42.699269]},
{"type":"Point","coordinates":[23.308673,42.698213]},
{"type":"Polygon","coordinates":[[[23.306886,42.698974],[23.307783,42.698843],[23.307511,42.697892],[23.30942,42.697617],[23.309143,42.696712],[23.308979,42.696177],[23.30757,42.696396],[23.307074,42.696472],[23.306153,42.696618],[23.305797,42.69667],[23.305268,42.696749],[23.305194,42.69648],[23.305081,42.696072],[23.304812,42.695107],[23.304593,42.694318],[23.304384,42.693726],[23.304224,42.693922],[23.303618,42.694326],[23.303328,42.694507],[23.302789,42.69485],[23.302718,42.694937],[23.302629,42.695249],[23.302477,42.695856],[23.302316,42.696499],[23.302418,42.696873],[23.302644,42.697745],[23.302289,42.697802],[23.302103,42.697833],[23.302199,42.697907],[23.302425,42.698126],[23.302548,42.69828],[23.302655,42.698464],[23.302723,42.698636],[23.30285,42.699098],[23.302997,42.699581],[23.303157,42.699555],[23.304115,42.699405],[23.305478,42.699199],[23.305966,42.699125],[23.306886,42.698974]]]},
{"type":"Point","coordinates":[23.304481,42.700175]}
]
}
}

The solution where i convert GeometryCollection to points, polygons etc. not work because they have one properties.我将 GeometryCollection 转换为点、多边形等的解决方案不起作用,因为它们具有一个属性。 Is it have a simple and clean way to style GeometryCollection geometries without difficult work to divide the geometries for visualization then put them together.是否有一种简单而干净的方式来设置 GeometryCollection 几何图形的样式,而无需进行困难的工作来划分几何图形以进行可视化,然后将它们组合在一起。

use the pointToLayer option to style markers:使用pointToLayer选项设置标记样式:

geoGroup = L.geoJson(json,{
    style: {
        "color": "#ff7800",
        "weight": 5,
        "opacity": 0.65
    },
    pointToLayer: function(geoJsonPoint, latlng) {
        return L.marker(latlng, {icon: L.icon({iconUrl: 'https://leafletjs.com/examples/custom-icons/leaf-orange.png'})});
    }
}).addTo(map)

Finally i found a solution.最后我找到了解决方案。 I detect the type of geometry and if type of geometry is GeometryCollection i use eachLayer function to style all layers in. Then if layer have _latlng i set a icon, if not do other.我检测几何类型,如果几何类型是GeometryCollection我使用 eachLayer 函数来设置所有图层的样式。然后如果图层有 _latlng 我设置一个图标,如果没有其他。 I hope this can help someone like me.我希望这可以帮助像我这样的人。 I don't found other solutions in web.我没有在 web.xml 中找到其他解决方案。

var layers_tmp = new L.FeatureGroup();
L.geoJson(data, {
    onEachFeature: function (features, layer){
        if(layer.feature.geometry.type == 'Polygon' || layer.feature.geometry.type == 'MultiPolygon'){                                            
            var t_style = {
                "weight":'3',
                "opacity":'1',
                "color":"#fcba03",
                "fillOpacity":'0.5',
                "fillColor":"#fcba03"
            }   
            layer.setStyle(t_style);
        }
        else if(layer.feature.geometry.type == 'Point'){                                    
            var ico = L.icon({
                iconUrl: 'https://api2.datamap.bg/images/blue_icon.png',
                iconSize: [25, 25],
                iconAnchor: [15, 15],
                popupAnchor: [-10, -10]
            });                                       
            layer.setIcon(ico);                                      
        }  
        else if(layer.feature.geometry.type == 'GeometryCollection'){ 
            layer.eachLayer(function(layer_GeometryCollection){  
                if(layer_GeometryCollection._latlng){
                    var ico = L.icon({
                        iconUrl: 'https://api2.datamap.bg/images/blue_icon.png',
                        iconSize: [25, 25],
                        iconAnchor: [15, 15],
                        popupAnchor: [-10, -10]
                    });                                          
                    layer_GeometryCollection.setIcon(ico);
                }
                else{                                          
                    var t_style = {
                        "weight":'3',
                        "opacity":'1',
                        "color":"#fcba03",
                        "fillOpacity":'0.5',
                        "fillColor":"#fcba03"
                    }   
                    layer.setStyle(t_style);
                }
            });                                          
        }           
        layers_tmp.addLayer(layer);                                
    }
});                     
layers_tmp.addTo(mymap);

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

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