Maximum inscribed circle in a polygon - javascript

I need to draw a maximum inscribed circle in a polygon. I found a library - https://github.com/PieceMaker/max-inscribed-circle - after little of googling. I have to do something wrong as my interpretation returns wrong result ( the circle should be more on right and radius looks strange to me ):
var coords = [
[49.0138, 15],
[49.0138, 15.0167],
[49.0153, 15.0167]
];
var polygon = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [coords]
},
"properties": {
"id": 1
}
};
console.log(maxInscribedCircle(polygon, 7));
returns
{
geometry: {
coordinates: [49.0143, 15.011133333333333],
type: "Point"
},
properties: {
radius: 0.0004823742421792941,
units: "degrees"
}
}
I tried to switch [lat, lon] order, but I get same results.
The question Largest circle inside a non-convex polygon doesn't solve this issue as it describes different algorithm - it doesn't use https://github.com/PieceMaker/max-inscribed-circle library.
Any idea, why position is wrong? How to properly interpret radius - how can "degrees" be length units?

Related

How to use a geojson file with javascript in order to create polygones with leaflet?

I am trying to create a map with the limitations of the departments as polygons with leaflet. I have the geojson file on my computer. For that, I intend to use the polygon function of leaflet as follows;
var polygon = L.polygon(departementsmetropole.geojson).addTo(map);
</script>
As you can see, I don't know how to use it. My goal is to extract the coordinates of the files in order to put them in the function. The file being the fronteers of the departments, I can't add them manually because each department has around 5000 points of coordinates.
I am a beginner so, as you can see above, I tried to put the file directly where it should go by the coordinates, but it didn't work. I also tried to use the get method without success.
In official documentation you will get all necessary.
In addition, you have the following jsfiddle example https://jsfiddle.net/ToniBCN/8nft2yhm/
// center of the map
var center = [55.8, -4.2];
// Create the map
var map = L.map('map').setView(center, 3);
// a GeoJSON multipolygon
var mp = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-3.9, 56],
[-3.9, 55.6],
[-4.6, 55.6],
[-4.6, 56],
[-3.9, 56]
],
[
[-4.42136131224148, 55.9201880414654],
[-4.44608055051929, 55.8994054388937],
[-4.49963890012121, 55.8816929539651],
[-4.44196067747298, 55.8362196009829],
[-4.35269676146979, 55.8045881227693],
[-4.35818992553152, 55.7636605341908],
[-4.22772727906531, 55.7350629547249],
[-4.07391868533672, 55.7582517890959],
[-4.00937400761133, 55.7984131283508],
[-4.04095970096631, 55.868595920571],
[-4.14532981813928, 55.8947855700627],
[-4.27991233765179, 55.9148010288061],
[-4.29776512085243, 55.9586449375958],
[-4.42136131224148, 55.9201880414654]
]
]
},
"properties": {
"name": "MultiPolygon",
"style": {
color: "orange",
opacity: 1,
fillColor: "gray",
fillOpacity: 0.3
}
}
};
var mp2 = {
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-4.42136131224148, 55.9201880414654],
[-4.44608055051929, 55.8994054388937],
[-4.49963890012121, 55.8816929539651],
[-4.44196067747298, 55.8362196009829],
[-4.35269676146979, 55.8045881227693],
[-4.35818992553152, 55.7636605341908],
[-4.22772727906531, 55.7350629547249],
[-4.07391868533672, 55.7582517890959],
[-4.00937400761133, 55.7984131283508],
[-4.04095970096631, 55.868595920571],
[-4.14532981813928, 55.8947855700627],
[-4.27991233765179, 55.9148010288061],
[-4.29776512085243, 55.9586449375958],
[-4.42136131224148, 55.9201880414654]
]
]
},
"properties": {
"name": "MultiPolygon2",
"style": {
color: "red",
opacity: 1,
fillColor: "green",
fillOpacity: 0.3
}
}
};
new L.GeoJSON(mp, {
style: function(feature) {
return feature.properties.style
}
}).addTo(map);
new L.GeoJSON(mp2, {
style: function(feature) {
return feature.properties.style
}
}).addTo(map);
// Set up the OSM layer
L.tileLayer(
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);

How to plot GeoJson data in d3.js

I am trying to display a floorplan to my webapp using d3.js and vue js. The data comes from a .json file and is in a geojson format. I generated some test data from this geojson website. I was thinking I could use the d3.js path function to plot each different object to a svg element. Would this be the correct way to go about doing this? I have looked at this tutorial to make a united states map from geojson data. I was thinking this would be the right way to do it if you inputted different data. However my program spits out random rectangles to the webapp. I think this may be becauseof the projection I am using but Im not sure. I havent used d3.js like this before so its all new to me. I included my code in below. Any help is greatly appreciated and im open to possibly using a different java script library but d3js is preferred.
createFloormap(){
var svg = d3.select("svg")
var width = +svg.attr("width")
var height = +svg.attr("height")
var path = d3.geoPath().projection(d3.geoAlbersUsa().scale(500))
//var path = d3.geoPath()
//var path = d3.geoPath().projection(d3.geoMercator().scale(100))
var x = d3.scaleLinear()
.domain([1, 10])
.rangeRound([600, 860]);
var color = d3.scaleThreshold()
.domain(d3.range(2, 10))
.range(d3.schemeBlues[9]);
var promises = [
d3.json("../static/data.json")
//d3.json("https://raw.githubusercontent.com/adamjanes/udemy-d3/master/08/8.04/data/us-map.json")
]
Promise.all(promises).then(function(data){
ready(data[0]);
})
function ready(us) {
console.log(us)
svg.append("g")
.selectAll("path")
.data(us.features)
//.data(topojson.feature(us, us.objects.states).features)
.enter()
.append("path")
.attr("fill", "grey")
.attr("d", path)
.attr("stroke", "#fff")
.attr("stroke-width", .2)
}
}
},
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-144.140625,
45.583289756006316
],
[
-65.390625,
45.583289756006316
],
[
-65.390625,
69.28725695167886
],
[
-144.140625,
69.28725695167886
],
[
-144.140625,
45.583289756006316
]
]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
9.4921875,
39.36827914916014
],
[
159.609375,
39.36827914916014
],
[
159.609375,
70.02058730174062
],
[
9.4921875,
70.02058730174062
],
[
9.4921875,
39.36827914916014
]
]
]
}
}
]
}
My apologies, I mislead you when commenting on your last question. I read the code and saw an obvious issue - but missed the reference to a floor plan - which for the coordinates given was unlikely to be measured in latitude/longitude pairs. The answer below would be appropriate for a floor plan in lat/long pairs (as would be exported from geojson.io and because projection is less relevant at the building scale) or a geojson floor plan with coordinates in meters/feet.
Geojson in an arbitrary Cartesian coordinate system
You don't have geographic coordinates consisting of latitude/longitude pairs measured in degrees (as I thought when commenting), you have coordinates consisting of x,y values measured in some unit like metres or feet.
To project these corodinates we do not want to use d3.geoSomeProjection because these project latitude/longitude pairs on a sphere to a 2d plane. Nor do we want to use a null projection (the default projection for d3.geoPath) because that treats geojson coordinates as pixel coordinates (we can use a null projection when the coordinates in the geojson have been already been converted to pixel values - we know we don't want a null projection here because we have negative values).
Instead we can use d3.geoIdentity (the geo prefix indicates it is just part of the geo module of D3 but it doesn't require geographic coordinates). This "projection" allows us to apply some projection methods to the data, namely .center() or .scale(). D3 also has two convenience methods that set both simultaneously: fitExtent and fitSize which stretch and translate specified geojson to given dimensions:
var projection = d3.geoIdentity().fitSize([width,height],geoJsonObject)
var projection = d3.geoIdentity().fitExtent([[left,top],[right,bottom]],geoJsonObject)
So, with your data we get:
var data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-144.140625,
45.583289756006316
],
[
-65.390625,
45.583289756006316
],
[
-65.390625,
69.28725695167886
],
[
-144.140625,
69.28725695167886
],
[
-144.140625,
45.583289756006316
]
]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
9.4921875,
39.36827914916014
],
[
159.609375,
39.36827914916014
],
[
159.609375,
70.02058730174062
],
[
9.4921875,
70.02058730174062
],
[
9.4921875,
39.36827914916014
]
]
]
}
}
]
}
var width = 500;
var height = 300;
var svg = d3.select("svg")
.attr("width",width)
.attr("height",height);
var projection = d3.geoIdentity().fitSize([width,height],data)
var path = d3.geoPath(projection);
svg.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("d",path);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
One thing to note is that SVG coordinates space, to which d3.geoIdentity is treating coordinates as being in, has the opposite convention as might be expected: y=0 is at the top of the SVG with y values increasing as one moves down. If your coordinates appear to be upside down, then you can use d3.geoIdenity().fitSize(...).reflectY(true)

Google Maps - addGeoJson is not working for my file

addGeoJson is not working in google map for my file
please check below code that I am using in javascript
//create the map
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 6,
center: {lat:49.79, lng: -8.82}
});
// Load GeoJSON.
var promise = $.getJSON("Sensitive_Areas_Nitrates_Rivers.json"); //same as map.data.loadGeoJson();
promise.then(function(data){
cachedGeoJson = data; //save the geojson in case we want to update its values
console.log(cachedGeoJson);
map.data.addGeoJson(cachedGeoJson,{idPropertyName:"id"});
});
I have downloaded this file from here
you can check my JSON file
Sensitive_Areas_Nitrates_Rivers.json
also, you can check this link with polygon
I have used below JSON format so you can check it
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "EPSG:27700"
}
},
"features": [
{
"type": "Feature",
"id": 1,
"geometry": {
"type": "MultiLineString",
"coordinates": [
[
[
500051.6875,
224280.03130000085
],
[
500047.2812999999,
224277.6875
],
[
499977.5937999999,
224242.625
],
[
499976.6875,
224242.21880000085
]
]
]
},
"properties": {
"OBJECTID": 8,
"type_of_sa": "SA_N",
"datedesign": 1025136000000,
"name": "Rivers Itchen",
"length_km": 12,
"uwwtd_code": "UKENRI134",
"shape_Length": 12172.080443901654
}
}
]
}
[500051.6875, 224280.03130000085] - [X, Y] coordinates may be in EPSG: 27700 to EPSG:4326, Now we need to display these coordinates on google map, Is there any solution for this?
Since Google Maps expects GeoJSON to be in EPSG:4326, Sensitive_Areas_Nitrates_Rivers.json needs to be reprojected. QGIS, for instance, could be utilized for that matter (refer docs for a details)
Reprojected Sensitive_Areas_Nitrates_Rivers.json layer will be displayed like this:
You are getting coordinates in metres. For displaying in google map you need to convert it into [Lng, Lat].
For converting metres to [Lng, Lat] you need to change the projection from EPSG: 27700 to 4326
then only you are able to get this geojson in [Lng, Lat]
Tool you can use: QGIS Desktop 3.4.14
Link: https://qgis.org/en/site/forusers/download.html
After convert you need to export this file as feature.

How to display (antimeridian) vector tiles generated by geojson-vt in leaflet using L.CRS.Simple?

I have a GeoJSON simple data that i need to display on a leaflet map using L.CRS.Simple crs, because is antimeridian data, and sometimes, coordinates can be [450,389] (more than 180)
This is the very simple GeoJSON:
{
"type": "FeatureCollection",
"name": "entities",
"features": [
{
"type": "Feature",
"properties": {
"Layer": "0",
"SubClasses": "AcDbEntity:AcDbPolyline",
"EntityHandle": "1F9",
"style": "PEN(c:#FF0000)"
},
"geometry": {
"type": "LineString",
"coordinates": [
[
0,
0
],
[
0,
150
],
[
150,
150
],
[
150,
0
],
[
0,
0
]
]
}
}
]
}
Using geojson-vt, (demo page) i'm getting this rectangle:
I made some modifications to geojson-vt lib:
Projection functions:
function projectX(x, simple, projectionFactor) {
return x / 256 + 1;
}
function projectY(y, simple, projectionFactor) {
return - y / 256 + 0.5;
}
I added to GeoJSONVT.prototype.getTile function this line:
y = y + (1 << (z - 1)); // xy map
And the result is (markers are placed on [0,0],[150,0],[150,150],[0,150]):
Any suggestion? Why i'm losing tiles here?
I recommend you read this: https://macwright.org/2016/09/26/the-180th-meridian.html
Quoting the GeoJSON spec recommended solution:
In representing Features that cross the antimeridian, interoperability is improved by modifying their geometry. Any geometry that crosses the antimeridian SHOULD be represented by cutting it in two such that neither part’s representation crosses the antimeridian. - GeoJSON Spec, 3.1.9

Create point with Geojson and coordinate table

I am currently working on a blog using the template "Fly to a location based on scroll position". However, i have a huge amount of points to display due to the use I'm making of it. Therefore, I intend to create a table that would contain the coordinates of the marker to display on the map. However, I don't manage to get a fully functional table. I can see in my code that the for loop is being ran, but the markers don't display.
I know i have to use function to put parameter but i don't know how whith Geojson.
Could you help me with this issue?
Ruman
code
var tab_coordo = [-5.949547290802002,54.6500264517435,-9.42651,52.97188,-9.465258121490479,51.94015569078675,12.352237701416016, 45.4577225021236];
for (tab_coordo = 0; tab_coordo < tab_coordo.length; tab_coordo++) {
var geojson ={
"features": [{
"type": "Feature",
"geometry": {
"type": "Point", "coordinates": [tab_coordo, tab_coordo++]//ireland cavehills
},
"properties": {
"title" : "jaimiejourneys",
"video": ("<iframe src='https://www.instagram.com/p/BWbCDZKA-Nu/embed' width='200' height='200' frameborder='0' scrolling='no'></iframe>")
}
},
]
}
// add markers to map
geojson.features.forEach(function(marker) {
// create a HTML element for each feature
var el = document.createElement('div');
el.className = 'marker';
// make a marker for each feature and add to the map
new mapboxgl.Marker(el, { offset: [-50 / 2, -50 / 2] })
.setLngLat(marker.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML('<p>' + marker.properties.video + '</p>'))
.addTo(map);
});
}
It resolved thanks for helping :)
var tab_coordo = [
-5.949547290802002, 54.6500264517435,
-9.42651,52.97188,
-9.465258121490479,51.94015569078675,
12.352237701416016, 45.4577225021236
12.411632537841797, 45.488298185683945
];
var coordo= tab_coordo.length;
for (var inc = 0; inc < coordo; inc=inc+2) {
//var inc_coordo = inc;
var geojson ={
"features": [{
"type": "Feature",
"geometry": {
"type": "Point", "coordinates": [tab_coordo[inc], tab_coordo[inc+1]]
},
"properties": {
"title" : "jaimiejourneys",
"video": ("<iframe src='https://www.instagram.com/p/BWbCDZKA-Nu/embed' width='200' height='200' frameborder='0' scrolling='no'></iframe>")
}
},
]
}

Categories