Complete an open polygon from a KML - javascript

I am working on an app that tests whether or not a certain coordinate is in the "beam" of a satellite transponder. My code works well except for cases of an open polygon. I was just closing these polygons by adding a coordinate on the end that was the same as the first but that is not a good approach as seen in the cases in the image I attached. The black represents how they are supposed to be completed.
I am parsing a KML that contains these polygons that are in the form of a LinearRing. They are not always counter-clockwise as they are supposed to be so I can't go from that clue.
For the yellow example, I thought about just using the coordinates on the two ends and fixing the longitude and generating latitude values until they matched up.
This approach fails for the blue example because of the pole issue but I could flip 180 degrees once I got to the pole. I also am not sure how to decide to go up in latitude or down. Obviously the semi-circle opens up towards the north so I would go that way but I can't figure out a reliable test for how it opens because of the red example. It mostly opens up toward the north (which is the way it should) but the ends start to go south so I couldn't just test the ends because it would look like it is opening up to the south. Is there a way to test to see what direction a parabola "mostly" opens up towards?
Something that might make it easy is that since it is a geo satellite, it can only see half of the earth centered at 0 degrees latitude. That is why I was thinking of traversing up or down a fixed longitude.
Another thing I was thinking about...could I treat this as a pseudo-cartesian system since I am a satellite looking at half of the earth. It pretty much resembles an skewed x-y system.
My question is, what is the best approach in completing the polygon and preserving the intended beam pattern?
EDIT: I could use the end points to calculate a point between the ends and then get the slope of the bisector using a middle point of the original curve. This would give me the direction of how it opens up.
y+, x+ : it opens toward the upper right
y+, x- : it opens toward the upper left
y-, x+ : it opens toward the lower right
y-, x- : it opens toward the lower left
From there, I am not sure how to generate the points. Can I just use the longitude of one of the end points and keep that fixed while iterating through latitudes around the globe until it matches the latitude of the other end point? I feel like I am oversimplifying it. I would hate to get it "working" and then realize it was a waste because it only works for a certain test case.

Related

If I have a GeoJSON file of a certain city's wards, how would I figure out which ward I'm in based on my lat/long coordinates?

Apologies in advance if this might seem like a silly question with an easy answer, or if its too vague, but I really am very new to the whole Geocoding shabang so I might not be able to ask the best questions yet.
Let's say I have the GeoJSON file for Philadelphia (https://hub.arcgis.com/datasets/phl::political-wards/explore?location=39.965479%2C-75.035211%2C11.78). I input a pair of coordinates for the Philadelphia City Hall, for example:
Latitude: 39.953306°
Longitude: -75.163577°. What would I need to do to get back the exact ward those coordinates lie in? In JavaScript (Node.js) ideally but any language would work as long as I understand the logic and steps I'd need to take.
Also, feel free to direct me to any resources/articles/videos/etc that would be useful to help me learn more about this kind of stuff.
If you have a polygon (a mathematical one, what GeoJSON would call a linear ring), and a point, imagine a line from the point to the first coordinate of the polygon. As you move the end of your line to the second coordinate of the polygon, your line moves by some angle (might be positive, might be negative, might be zero). Similarly from the second to third and so on. Add up the angles: if the result is +/-360 degrees, your point is inside the polygon. If zero, then outside. Search "winding number" for details.
Of course, it would be inefficient to test all polygons, so you make some kind of index of the bounding boxes of the polygons, and only inspect those whose bounding box contains your point, these are called R-trees (there are many variants, and lots of software available for this).

Algorithm to decompose Polygons into lineStrings (Headlands from Plots)

Consider the following polygon (an agricultural plot)
From this polygon, I would like to extract the "headlands" of the plot, being the consecutive lines (sides) of the polygon (Wikipedia) used for turning on the field. While often only the rows running perpendicular to the lay of the field are considered, I need all sides of the polygon.
Here, a consecutive line means any set of coordinates, where the angle between any two coordinates of the set is not larger than a value X (e.g 30 degrees).
For the given example, the resulting headlands should look like the following:
I wrote a small algorithm trying to accomplish this, basically checking the angle between two coordinates and either pushing the given coordinate to the existing lineString if the angle is below X degrees or creating a new lineString (headland) if not.
Check out the following Gist
However, in some cases corners of a field are rounded, therefore may consist of many coordinates within small distances of each other. The relative angles then may be less than the value X, even though the corner is too sharp to actually be cultivated without turning.
In order to overcome that issue, I added an index that increases whenever a coordinate is too close for comparison, so that the next coordinate will be checked against the initial coordinate. Check out the following Gist.
This works for simple plots like the one in the example, however I am struggling with more complex ones as the following.
Here, the bottom headland is recognised as one lineString together with the headland on the right, even though optically a sharp corner is given. Also, two coordinates in the upper right corner were found to be a separate headland even though they should be connected to the right headland. The result should therefore yield in the following:
What I would like to know is if there is an approach that efficiently decomposes any polygon into it's headlands, given a specific turning angle. I set up a repo for the code here, and an online testing page with many examples here if that helps.

Get center of geojson Continent/Country/State with leaflet

Is there a way of finding a center for countries/continents which consist of more than one polygon object(ex. USA, Canada, which have an islands besides main land part)? I was trying to use leaflet's Layer.getCenter() or even Layer.getBounds().getCenter(), but those methods certainly don't work for this type of countries and return a "no-go" results.
Example can be seen by the following link (leaflet playground). Just scroll and click on US or Canada and see where circleMarker will appear. Then try clicking on smaller entities, like some islands on south of US, they shall place this marker precisely on center of'em:
http://playground-leaflet.rhcloud.com/voyi/1/edit?html,output
Leaflet can only calculate the center of the bounding box of a feature. With a bit of help from other libraries (such as Turf.js) you can calculate the centroid of the polygon or (multipolygon).
In any case, you are getting confused because sometimes the centroid is not within the polygon (or multipolygon):
(source: postgis.net)
(Figure 1. Centroid of a polygon as per PostGIS's ST_Centroid documentation)
So I guess that what you really wanted to ask is:
Given a polygon or multipolygon, how can I calculate a center (or center-like point) which is guaranteed to be within the polygon and looks visually in the center of it, in order to add symbolizers to that point with Leaflet?
And for that, the answer is "pole of inaccessibility" as implemented by polylabel: «the most distant internal point from the polygon outline».

Is there a way to determine if a given point (lat, long) is inside a drawn polygon?

I have a KML file with about 5 polygon placemarks and I was wondering if there's a way to determine if a specified point is inside any of the polygons. Does Google Earth have a function to do that or can one be written?
Use the ray casting method for point in polygon test.
The test shoots off a ray towards infinity (arbitrarily chosen direction, usually parallel to one of the axis used for code simplicity and speed) from the test point and counts the intersections with the polygon in question. If the number of intersections are odd, then the point lies within the polygon, else it lies outside. Repeat this test for all the polygons.
check out this link for further explanation and degenerate and special cases.
pip wikipedia .
I've implemented this function in C so let me know if you need any pointers.
You could alternatively also use the Winding Number test. WN wikipedia
They may have similar performances depending on the implementation and the platform.
The implementations you'l find may be mostly for Cartesian co-ordinates. Keep in mind that they'l work perfectly fine as it is, with geographic co-ordinates as well.

Merge two svg path elements programmatically

I am rendering a map out of SVG paths (using jVectormap).
There are cases where one region has to be merged with the neighboring region.
Unfortunately both regions don't touch each other and I have to interpolate to fill the space in between.
jVectormap uses very simple SVG paths with M to set the the absolute startpoint and l to connect relative points.
Does any of the SVG libraries cover such an operation?
I haven't tried this, but you may get around it by running the converter at jVectormap with the following parameters:
--buffer_distance=0
--where="ISO='region_1' OR ISO='region_2'"
Where region_1 and region_2 are the two regions that you need to merge.
Solving the problem this way also means that the generated SVG paths are true to the original coordinates, whereas a following fix may lead to some (probably minor) inconsistencies.
This might not be the kind of answer you're looking for, but using Raphael.js you could loop over the entire length of the path of one region getPointAtLength(), comparing it with all points of the second region. If the coordinates are closer than n pixels from any coordinates on the second region and the previous coordinates weren't, than that could be regarded a "glue" point. You would then jump to the second regio and start looping over it, if the next point is still closer than n points, than go in the opposite direction, if still closer change direction and go farther along the path till finding a point that's farther away from the original region than n pixels. Continue looping in that direction till once again finding a new "glue" point, where once again you will switch to the original region in the manner described and all points which weren't covered in this final loop could be discarded (or you could simply create a new shape based on the points you came across whilst looping over the length of the original region.
True enough, it's not the easiest script to make, but it should be quite do-able I believe, especially when you can use a function like getPointAtLength to find the points between the defined svg points (though you need to only 'record' the defined points, and that's sort of the hard path as Raphael.js doesn't excitedly have any functions which would help with this, still even that shouldn't be too hard to match up by hand (in code of course)).

Categories

Resources