簡體   English   中英

當孔與多邊形邊界重疊時,傳單js填充顏色錯誤

[英]leaflet js fill color error when hole overlaps boundary of polygon

我在傳單 js 地圖(在 bing 地圖上)中定義了一個多邊形。
這個多邊形有兩個洞(黃色多邊形)。 第二個孔多邊形與主多邊形的外邊界重疊。

在此處輸入圖片說明

問題:

延伸超過主多邊形外邊緣的第二個多邊形部分將獲得主多邊形的填充顏色。

在這種情況下,主要多邊形是紅色的,被移除的整個多邊形是黃色的

我在附圖中圈出了這個問題。

以下是我重新創建問題小提琴

有人可以幫我弄清楚如何在沒有這種重疊顏色問題的情況下從紅色多邊形中刪除第二個黃色形狀的部分嗎?

為了清楚起見,這里是小提琴中的所有代碼:

// Create the map
var map = L.map('map').setView([53.631611, -113.323975], 9);

// Set up the OSM layer
L.tileLayer(
    'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', 
    {maxZoom: 18}).addTo(map);

//Create Polygon Orange
var polyOrange = new L.Polygon([
            [[53.569268602609704,-113.71411800384523], [53.51214299292513,-113.71411800384523], [53.51214299292513,-113.68802547454835], [53.403391858715274,-113.6907720565796], [53.40461992848445,-113.64957332611085], [53.3960226956682,-113.64614009857179], [53.39684155458476,-113.34332942962648], [53.4471711023092,-113.35744857788087], [53.4471711023092,-113.24483871459962], [53.57212285981298,-113.24445247650148], [53.58149977709897,-113.29389095306398], [53.58435320870081,-113.36118221282959], [53.62102302920731,-113.3447027206421], [53.646672964306994,-113.36942195892335], [53.64952199454264,-113.57116699218751], [53.669866612978275,-113.6345958709717], [53.65603334084723,-113.70188713073732], [53.57620003591595,-113.68678092956544]] 

], {color:'orange', opacity:1, fillOpacity:0.05});

//Create polygon YELLOW
var polyYellow = new L.Polygon([
    [ 
        [[53.716006, -113.252565],[53.715496, -113.228546],[53.717052, -113.215209],[53.734927, -113.197527],[53.753505, -113.172980],[53.768016, -113.168688],[53.774205, -113.157874],[53.774284, -113.148883],[53.715867, -113.149098],[53.715934, -113.172036],[53.686769, -113.172207],[53.686935, -113.196896],[53.367132, -113.197204],[53.366818, -113.221196],[53.337761, -113.220792],[53.337882, -113.801601],[53.367033, -113.807995],[53.367197, -113.836702],[53.716273, -113.836434]], 
        [[53.569268602609704,-113.71411800384523], [53.51214299292513,-113.71411800384523], [53.51214299292513,-113.68802547454835], [53.403391858715274,-113.6907720565796], [53.40461992848445,-113.64957332611085], [53.3960226956682,-113.64614009857179], [53.39684155458476,-113.34332942962648], [53.4471711023092,-113.35744857788087], [53.4471711023092,-113.24483871459962], [53.57212285981298,-113.24445247650148], [53.58149977709897,-113.29389095306398], [53.58435320870081,-113.36118221282959], [53.62102302920731,-113.3447027206421], [53.646672964306994,-113.36942195892335], [53.64952199454264,-113.57116699218751], [53.669866612978275,-113.6345958709717], [53.65603334084723,-113.70188713073732], [53.57620003591595,-113.68678092956544]] 
    ],
    [ 
        [[53.555985, -114.002024],[53.555804, -114.038727],[53.541397, -114.038512],[53.541372, -114.050958],[53.512009, -114.050958],[53.512111, -114.026410],[53.505169, -114.026410],[53.505373, -113.971564],[53.512034, -113.971650],[53.512034, -113.959076],[53.520338, -113.959179],[53.519726, -113.885364],[53.541153, -113.885364],[53.541101, -113.845993],[53.571438, -113.846851],[53.570012, -113.885364],[53.571082, -113.916435],[53.569349, -113.959007],[53.555451, -113.959383]]
    ]
], {color:'yellow', opacity:1, fillOpacity:0.05});

// CREATE POLYGONE RED
var polyRed = new L.Polygon([
    [ 
        [[53.773877,-114.001813],[53.774105,-113.998508],[53.774105,-113.917720],[53.803400,-113.917398],[53.803575,-113.661065],[53.812242,-113.660379],[53.818221,-113.652482],[53.818221,-113.620124],[53.803575,-113.620124],[53.803499,-113.347294],[53.818120,-113.347380],[53.818145,-113.345062],[53.830178,-113.334934],[53.835015,-113.335750],[53.842232,-113.324506],[53.840485,-113.321759],[53.845245,-113.314550],[53.845448,-113.309958],[53.847321,-113.309271],[53.847296,-113.305537],[53.845827,-113.306310],[53.845827,-113.304164],[53.844030,-113.306267],[53.842283,-113.310601],[53.825365,-113.310601],[53.825340,-113.322317],[53.803524,-113.322961],[53.803244,-113.124330],[53.774265,-113.124223],[53.715852,-113.124309],[53.715846,-113.098581],[53.571181,-113.098811],[53.366714,-113.098865],[53.366702,-113.074291],[53.279625,-113.074530],[53.279664,-113.098670],[53.279606,-113.220582],[53.250595,-113.220603],[53.250582,-113.488503],[53.250531,-113.499918],[53.235790,-113.499918],[53.235892,-113.561716],[53.250531,-113.561716],[53.250556,-113.598323],[53.257720,-113.598452],[53.257771,-113.610425],[53.265139,-113.610468],[53.265062,-113.927419],[53.366600,-113.927333],[53.366715,-114.001904]]
    ],
    [ 
        [[53.716006, -113.252565],[53.715496, -113.228546],[53.717052, -113.215209],[53.734927, -113.197527],[53.753505, -113.172980],[53.768016, -113.168688],[53.774205, -113.157874],[53.774284, -113.148883],[53.715867, -113.149098],[53.715934, -113.172036],[53.686769, -113.172207],[53.686935, -113.196896],[53.367132, -113.197204],[53.366818, -113.221196],[53.337761, -113.220792],[53.337882, -113.801601],[53.367033, -113.807995],[53.367197, -113.836702],[53.716273, -113.836434]],
        [[53.555985, -114.002024],[53.555804, -114.038727],[53.541397, -114.038512],[53.541372, -114.050958],[53.512009, -114.050958],[53.512111, -114.026410],[53.505169, -114.026410],[53.505373, -113.971564],[53.512034, -113.971650],[53.512034, -113.959076],[53.520338, -113.959179],[53.519726, -113.885364],[53.541153, -113.885364],[53.541101, -113.845993],[53.571438, -113.846851],[53.570012, -113.885364],[53.571082, -113.916435],[53.569349, -113.959007],[53.555451, -113.959383]]
    ]
], {color:'red', opacity:1, fillOpacity:0.03});

//Add polygons to map
polyRed.addTo(map); 
polyYellow.addTo(map); 
polyOrange.addTo(map);

你只需要在 html 頁面上瘦:

並鏈接到leaflet.js 和.css cdn

您的外環(即 RED 多多邊形定義中的第一個多邊形數組)應該限制您的幾何圖形,包括孔。

在您當前的定義中,第二個孔(即紅色多多邊形定義中第二個多邊形的第二個環)比外環向西延伸(某些坐標的經度低於外環中最低的一個)。

這種不一致使得渲染難以正確表示帶孔的多面體,導致孔的一部分被塗上填充顏色。

一個“簡單”的解決方案是手動修改您的外圈以完全包括您的孔:

 // Create the map var map = L.map('map').setView([53.54, -113.9], 10); // Set up the OSM layer L.tileLayer( 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18 }).addTo(map); //Create polygon YELLOW var polyYellow = new L.Polygon([ [ [ [53.716006, -113.252565], [53.715496, -113.228546], [53.717052, -113.215209], [53.734927, -113.197527], [53.753505, -113.172980], [53.768016, -113.168688], [53.774205, -113.157874], [53.774284, -113.148883], [53.715867, -113.149098], [53.715934, -113.172036], [53.686769, -113.172207], [53.686935, -113.196896], [53.367132, -113.197204], [53.366818, -113.221196], [53.337761, -113.220792], [53.337882, -113.801601], [53.367033, -113.807995], [53.367197, -113.836702], [53.716273, -113.836434] ], [ [53.569268602609704, -113.71411800384523], [53.51214299292513, -113.71411800384523], [53.51214299292513, -113.68802547454835], [53.403391858715274, -113.6907720565796], [53.40461992848445, -113.64957332611085], [53.3960226956682, -113.64614009857179], [53.39684155458476, -113.34332942962648], [53.4471711023092, -113.35744857788087], [53.4471711023092, -113.24483871459962], [53.57212285981298, -113.24445247650148], [53.58149977709897, -113.29389095306398], [53.58435320870081, -113.36118221282959], [53.62102302920731, -113.3447027206421], [53.646672964306994, -113.36942195892335], [53.64952199454264, -113.57116699218751], [53.669866612978275, -113.6345958709717], [53.65603334084723, -113.70188713073732], [53.57620003591595, -113.68678092956544] ] ], [ [ [53.555985, -114.002024], [53.555804, -114.038727], [53.541397, -114.038512], [53.541372, -114.050958], [53.512009, -114.050958], [53.512111, -114.026410], [53.505169, -114.026410], [53.505373, -113.971564], [53.512034, -113.971650], [53.512034, -113.959076], [53.520338, -113.959179], [53.519726, -113.885364], [53.541153, -113.885364], [53.541101, -113.845993], [53.571438, -113.846851], [53.570012, -113.885364], [53.571082, -113.916435], [53.569349, -113.959007], [53.555451, -113.959383] ] ] ], { color: 'yellow', opacity: 1, fillOpacity: 0.5 }); // CREATE POLYGONE RED var polyRed = new L.Polygon([ // First polygon. [ // First ring = outer ring, must bound the surface. [ [53.773877, -114.001813], [53.774105, -113.998508], [53.774105, -113.917720], [53.803400, -113.917398], [53.803575, -113.661065], [53.812242, -113.660379], [53.818221, -113.652482], [53.818221, -113.620124], [53.803575, -113.620124], [53.803499, -113.347294], [53.818120, -113.347380], [53.818145, -113.345062], [53.830178, -113.334934], [53.835015, -113.335750], [53.842232, -113.324506], [53.840485, -113.321759], [53.845245, -113.314550], [53.845448, -113.309958], [53.847321, -113.309271], [53.847296, -113.305537], [53.845827, -113.306310], [53.845827, -113.304164], [53.844030, -113.306267], [53.842283, -113.310601], [53.825365, -113.310601], [53.825340, -113.322317], [53.803524, -113.322961], [53.803244, -113.124330], [53.774265, -113.124223], [53.715852, -113.124309], [53.715846, -113.098581], [53.571181, -113.098811], [53.366714, -113.098865], [53.366702, -113.074291], [53.279625, -113.074530], [53.279664, -113.098670], [53.279606, -113.220582], [53.250595, -113.220603], [53.250582, -113.488503], [53.250531, -113.499918], [53.235790, -113.499918], [53.235892, -113.561716], [53.250531, -113.561716], [53.250556, -113.598323], [53.257720, -113.598452], [53.257771, -113.610425], [53.265139, -113.610468], [53.265062, -113.927419], [53.366600, -113.927333], [53.366715, -114.001904], // up to here, -114.001904 is the West-most longitude [53.505169, -114.001904], // Intersection point, manually built, but you can see a small gap. // Reversed order [53.505169, -114.026410], // More West than -114.001904 [53.512111, -114.026410], // More West than -114.001904 [53.512009, -114.050958], // More West than -114.001904 [53.541372, -114.050958], // More West than -114.001904 [53.541397, -114.038512], // More West than -114.001904 [53.555804, -114.038727], // More West than -114.001904 [53.555985, -114.002024], // More West than -114.001904 [53.555985, -114.001813] // Intersection point, manually built ] // No other ring, therefore it should have no hole, but see 2nd polygon below. ], // Second polygon, incorrectly rendered by Leaflet as a hole. [ // First ring = outer ring, but incorrectly rendered by Leaflet as 1st hole of 1st polygon. [ [53.716006, -113.252565], [53.715496, -113.228546], [53.717052, -113.215209], [53.734927, -113.197527], [53.753505, -113.172980], [53.768016, -113.168688], [53.774205, -113.157874], [53.774284, -113.148883], [53.715867, -113.149098], [53.715934, -113.172036], [53.686769, -113.172207], [53.686935, -113.196896], [53.367132, -113.197204], [53.366818, -113.221196], [53.337761, -113.220792], [53.337882, -113.801601], [53.367033, -113.807995], [53.367197, -113.836702], [53.716273, -113.836434] ], // Second ring = hole. [ [53.555985, -114.002024], // More West than -114.001904 [53.555804, -114.038727], // More West than -114.001904 [53.541397, -114.038512], // More West than -114.001904 [53.541372, -114.050958], // More West than -114.001904 [53.512009, -114.050958], // More West than -114.001904 [53.512111, -114.026410], // More West than -114.001904 [53.505169, -114.026410], // More West than -114.001904 [53.505373, -113.971564], [53.512034, -113.971650], [53.512034, -113.959076], [53.520338, -113.959179], [53.519726, -113.885364], [53.541153, -113.885364], [53.541101, -113.845993], [53.571438, -113.846851], [53.570012, -113.885364], [53.571082, -113.916435], [53.569349, -113.959007], [53.555451, -113.959383] ] ] ], { color: 'red', opacity: 1, fillOpacity: 0.3 }); //Add polygons to map polyRed.addTo(map); polyYellow.addTo(map);
 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" /> <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script> <div id="map" style="height: 200px"></div>

順便說一句,這突出了 Leaflet 中的一個不一致之處,即使用多多邊形定義的第一個多邊形作為外環,將第二個多邊形的所有環用作第一個多邊形的孔。 文檔示例堅持 GeoJSON 規范。 這可能與傳單問題 #3498 有關

更強大的解決方案是從外圈正確移除孔,例如使用Turf.js difference

 var outerRingLatLng = [ [53.773877, -114.001813], [53.774105, -113.998508], [53.774105, -113.917720], [53.803400, -113.917398], [53.803575, -113.661065], [53.812242, -113.660379], [53.818221, -113.652482], [53.818221, -113.620124], [53.803575, -113.620124], [53.803499, -113.347294], [53.818120, -113.347380], [53.818145, -113.345062], [53.830178, -113.334934], [53.835015, -113.335750], [53.842232, -113.324506], [53.840485, -113.321759], [53.845245, -113.314550], [53.845448, -113.309958], [53.847321, -113.309271], [53.847296, -113.305537], [53.845827, -113.306310], [53.845827, -113.304164], [53.844030, -113.306267], [53.842283, -113.310601], [53.825365, -113.310601], [53.825340, -113.322317], [53.803524, -113.322961], [53.803244, -113.124330], [53.774265, -113.124223], [53.715852, -113.124309], [53.715846, -113.098581], [53.571181, -113.098811], [53.366714, -113.098865], [53.366702, -113.074291], [53.279625, -113.074530], [53.279664, -113.098670], [53.279606, -113.220582], [53.250595, -113.220603], [53.250582, -113.488503], [53.250531, -113.499918], [53.235790, -113.499918], [53.235892, -113.561716], [53.250531, -113.561716], [53.250556, -113.598323], [53.257720, -113.598452], [53.257771, -113.610425], [53.265139, -113.610468], [53.265062, -113.927419], [53.366600, -113.927333], [53.366715, -114.001904], [53.773877, -114.001813] // Finish by first position for GeoJSON compliancy. ]; var hole1LatLng = [ [53.716006, -113.252565], [53.715496, -113.228546], [53.717052, -113.215209], [53.734927, -113.197527], [53.753505, -113.172980], [53.768016, -113.168688], [53.774205, -113.157874], [53.774284, -113.148883], [53.715867, -113.149098], [53.715934, -113.172036], [53.686769, -113.172207], [53.686935, -113.196896], [53.367132, -113.197204], [53.366818, -113.221196], [53.337761, -113.220792], [53.337882, -113.801601], [53.367033, -113.807995], [53.367197, -113.836702], [53.716273, -113.836434], [53.716006, -113.252565] // Finish by first position for GeoJSON compliancy. ]; var hole2LatLng = [ [53.555985, -114.002024], [53.555804, -114.038727], [53.541397, -114.038512], [53.541372, -114.050958], [53.512009, -114.050958], [53.512111, -114.026410], [53.505169, -114.026410], [53.505373, -113.971564], [53.512034, -113.971650], [53.512034, -113.959076], [53.520338, -113.959179], [53.519726, -113.885364], [53.541153, -113.885364], [53.541101, -113.845993], [53.571438, -113.846851], [53.570012, -113.885364], [53.571082, -113.916435], [53.569349, -113.959007], [53.555451, -113.959383], [53.555985, -114.002024] // Finish by first position for GeoJSON compliancy. ]; var outerRing = turf.polygon([latLngArrayToLngLat(outerRingLatLng)]); var holes = turf.multiPolygon([ [latLngArrayToLngLat(hole1LatLng)], [latLngArrayToLngLat(hole2LatLng)] ]); var result = turf.difference(outerRing, holes); var resultGeoJSON = turf.getGeom(result); var map = L.map('map'); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }).addTo(map); var geojsonLayer = L.geoJSON(resultGeoJSON, { style: { color: 'red', opacity: 1, fillOpacity: 0.3 } }).addTo(map); map.fitBounds(geojsonLayer.getBounds()); function latLngArrayToLngLat(latLngArray) { return latLngArray.map(latLngToLngLat); } function latLngToLngLat(latLng) { return [latLng[1], latLng[0]]; } //Create polygon YELLOW var polyYellow = new L.Polygon([ [ [ [53.716006, -113.252565], [53.715496, -113.228546], [53.717052, -113.215209], [53.734927, -113.197527], [53.753505, -113.172980], [53.768016, -113.168688], [53.774205, -113.157874], [53.774284, -113.148883], [53.715867, -113.149098], [53.715934, -113.172036], [53.686769, -113.172207], [53.686935, -113.196896], [53.367132, -113.197204], [53.366818, -113.221196], [53.337761, -113.220792], [53.337882, -113.801601], [53.367033, -113.807995], [53.367197, -113.836702], [53.716273, -113.836434] ], [ [53.569268602609704, -113.71411800384523], [53.51214299292513, -113.71411800384523], [53.51214299292513, -113.68802547454835], [53.403391858715274, -113.6907720565796], [53.40461992848445, -113.64957332611085], [53.3960226956682, -113.64614009857179], [53.39684155458476, -113.34332942962648], [53.4471711023092, -113.35744857788087], [53.4471711023092, -113.24483871459962], [53.57212285981298, -113.24445247650148], [53.58149977709897, -113.29389095306398], [53.58435320870081, -113.36118221282959], [53.62102302920731, -113.3447027206421], [53.646672964306994, -113.36942195892335], [53.64952199454264, -113.57116699218751], [53.669866612978275, -113.6345958709717], [53.65603334084723, -113.70188713073732], [53.57620003591595, -113.68678092956544] ] ], [ [ [53.555985, -114.002024], [53.555804, -114.038727], [53.541397, -114.038512], [53.541372, -114.050958], [53.512009, -114.050958], [53.512111, -114.026410], [53.505169, -114.026410], [53.505373, -113.971564], [53.512034, -113.971650], [53.512034, -113.959076], [53.520338, -113.959179], [53.519726, -113.885364], [53.541153, -113.885364], [53.541101, -113.845993], [53.571438, -113.846851], [53.570012, -113.885364], [53.571082, -113.916435], [53.569349, -113.959007], [53.555451, -113.959383] ] ] ], { color: 'yellow', opacity: 1, fillOpacity: 0.5 }); //Add polygons to map polyYellow.addTo(map);
 <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" /> <script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script> <script src="https://unpkg.com/@turf/turf@5.1.6/turf.js"></script> <div id="map" style="height: 200px"></div>

當然,您可以簡單地將此重構的結果保存為您的 RED 多邊形的新定義,該多邊形現在只有 1 個孔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM