How to use R-Tree of NetTopologySuite in GMap.NET to display abundant marker WPF - wpf

I am using GMap.NET to display a lot of Marker (about more than 10.000 markers). R-Tree is a solution to optimize render markers at area which window is showing.
STRtree in NetTopologySuite is a library to support R-tree. But I'm not sure it suitable for this problem.
My question is how to use R-Tree in NetTopologySuite to show markers. I don't know how to use library. (I'm new in WPF). How to catch event when GMap render marker to get marker from R-Tree and remove previous marker at same time?
Please give me some example about R-tree in NetTopologySuite.

I did it by my way. This is the way STRtree is decleared: STRtree<Coordinate> gpsSTRtree = new STRtree<Coordinate>(); You can change Coordinate data type by any other data type but STRtree need to Envelope to insert to tree.
For example: insert to STRtree:
Coordinate gps = new Coordinate(9.74233, 106.0213);
Envelope item = new Envelope(gps);
gpsSTRtree.Insert(item, gps);
Envelope is a node in STRtree to store the boundary of item.
STRtree query from two points. point1 and point2 are Coordinate
Envelope gpsQuery = new Envelope(p1, p2);
Coordinate gpsItems = gpsSTRtree.Query(gpsQuery);
Then you have a list of Coordinate
Good luck

Related

How to create a grid of 50sq km Rectangles or Hexagons in React Map GL(Mapbox) and Deck.gl, that covers an entire country

I'm trying to create a Grid Layer of Either Rectangles or Hexagons in React Map GL(Map Box) and Deck GL, that cover an entire country.
This is what I'm trying to achieve: http://webcoveragemap.rootmetrics.com/en-US
These are the Solutions I've found:
https://deck.gl/#/documentation/deckgl-api-reference/layers/s2-layer
https://deck.gl/#/documentation/deckgl-api-reference/layers/h3-cluster-layer
The problem I'm facing with is that s2-layer uses S2 Cell token (Which I can't seem to understand how to calculate and similarly h3-cluster-layer uses H3 and for that too I can't find any code samples for React. So can anybody explain me either how to use H3, S2 and calculate 50sq km boxes that can be viewed on React Map Gl with Deck GL (if needed). Or suggest another Solution?
Turns out there's java script version of H3-Core Library (A hexagon-based geographic grid system). https://www.npmjs.com/package/h3-js
All it require's to convert a lat/lng point to a hexagon index at some resolution is following code:
const h3Index = h3.geoToH3(37.3615593, -122.0553238, 7);
// -> '87283472bffffff'

Simplified GeoJSON reports fantom markers on google maps

I have a geography column in database. This column holds the original polygon. Next to it I have another column that holds the simplified version of this polygon. The simplification has been done with geography.Reduce()(I use tolerance of 100) function that operates with Douglas-Peucker algorithm. When the client asks for this area I fetch it from database and do a quick convert into GeoJSON and serve it to my client.
If I query the original polygon it will take good 20 seconds before it is successfully retreived but it works. In the end only problem is the speed and that is why I introdouced the second column that holds the simplified polygon. Fetching this polygon from database happens in an instant but a curious thing happens on the client side.
As you can see multiple markers are shown on my map. None of them are clickable expect the top most(slightly south-west from Melbourne) but this one is actually a marker that I have added. Where do the other ones come from?
Another thing I noticed is the more I reduce simplicity the less of these fanthom markers shows. So if I serve the original polygon as GeoJSON all is fine. As soon as I start simplifying I get these fantom markers.
When I query for this simplified polygon I use geography::STAsText() function. After that I use NetTopologySuite to read this as WKT and create a NetSuiteTopology Geometry object. With this object I create a Feature and use GeoJsonWriter to create the actual GeoJSON.
var query = new SqlQuery("Location")
.Select("LocationServicingAreaSimplified.STAsText()")
.Where("LocationID", SqlOp.Equals, "#LocationID");
// This object query will be convertet to
// SELECT LocationServicingAreaSimplified.STAsText() FROM Location WHERE LocationID = ?
query.Parameters.Add("#LocationID", LocationID);
var simplifiedPolygon = await query.ExecuteScalarAsync<string>();
var wktReader = new WKTReader() { DefaultSRID = 4326 };
var geoJsonWriter = new GeoJsonWriter();
var feature = new Feature
{
Geometry = wktReader.Read(simplifiedPolygon)
};
return geoJsonWriter.Write(feature);
After an extensive research I have concluded that the proces of simplification will produce points when some polygons are oversimplified. google maps will represent the points as markers therefore, the greater the simplification the more points are produced the more markers are present.
I have found an article where it is described how to get rid of these points but haven't yet tested it.
Hope this helps some spatial noob(like me).

react zoom/pan scatter plot, data filtering vs clip

I have a question in React implementation for zoom/pan function for a scatter plot.
I wonder what approach would be good and want to hear opinions of React & data visualization expert.
I am specifically interested in implementing zoom/pan function of a scatter plot that is dynamically changing data range to visualize.
(Approach 1) Given a data range (controlled by mouse wheel event), first, filter the data, and render circles () for the filtered data. In this case, each circle will be generated with new key such that
const circles = [];
filteredData.forEach( (d, index) => {
circleProps = { /*..compute circle props... (e.g. position within a SVG) */ }
circles.push(
<circle key={`circle-${index}`} {...circleProps} />
);
});
Thus, every time the data range changes, it will create new set of circles located within the range.
(Approach 2) Similar to Approach 1 but no filtering on the data. Instead, use clip path to visualize only the circles within the range. In this case, it will update entire circles according to re-calculated positions but it will only create the circles one time at the beginning.
What would better approach? Or, any other options to handle large-scale data? Also, please correct me if anything is wrong.
Thanks.

Leaflet JS: Custom 2D projection that uses meters instead of lat,long

I am working on a custom game map. This map is basically a raster image, overlayed with some paths and markers. I want to use Leaflet to display the map.
What I am struggling with, is that Leaflet uses Latitude and Longitude to calculate positions, while it uses meters for distances (path lengths, radii of circles, etc).
This is very understandable when dealing with a spherical world like our Earth, but it complicates the custom map, which is flat a lot.
I would like to be able to specify the positions in the same unit as the distances.
Now, by default Leaflet uses a Spherical Mercator projection. According to the Docs, it is possible to define your own projections and coordinate reference systems, but I have been unable to do this thus far.
How would this be possible? Or is there a simpler way?
You should take a look at the simple coordinate reference system (L.CRS.Simple) included with Leaflet:
A simple CRS that maps longitude and latitude into x and y directly. May be used for maps of flat surfaces (e.g. game maps).
You can define the CRS of your L.Map instead upon initialization like so:
new L.Map('myDiv', {
crs: L.CRS.Simple
});
Some further elaboration: As #ghybs pointed out in the comment below and the comment to your question the default sperical mercator projection (L.CRS.EPSG3857) already works in meters. When you calculate the distance between two coordinates, Leaflet returns meters, example:
var startCoordinate = new L.LatLng(0, -1);
var endCoordinate = new L.LatLng(0, 1);
var distance = startCoordinate.distanceTo(endCoordinate);
console.log(distance);
The above will print 222638.98158654713 to your console which is the distance between those two coordinates in meters. Problem is that when using spherical projection, distance between two coordinates will become less the further you get from the equator which will become problematic when creating a flat gameworld. That's why you should use L.CRS.Simple, you won't have said problem.

Configuring maxExtent and restrictExtent coordinates in OpenLayers

I'm very new to OpenLayers and working with GeoData; as such, I think I have a pretty noob question about configuring map bounds with OpenLayers. First, here's the map code I've made up...
function createMap(containerId){
return new OpenLayers.Map(containerId, {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
maxResolution:156543.0339,
numZoomLevels:4,
controls: [],
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
restrictExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
});
}
I have my map and I've loaded a GeoJSON layer of vector country shapes on top of it. So far so good. However, if I call zoomToMaxExtent on the map, the map zooms out to be a little tiny thumbnail-sized graphic in the center of my viewport rather than filling the frame. Then if I zoom in on the map, I can (seemingly) pan the map indefinitely in any direction rather than being constrained at the edges of the map shapes.
So I assume I'm doing something wrong with my maxExtent and restrictExtent settings, although I have no idea what it is. To be honest, I'm not sure what those huge bounding numbers are (found them in sample code). Essentially, by Lon/Lat coordinates, I think I'm just trying to restrict bounding to -180, -90, 180, 90 – which should provide a tight frame around the map geography, right? Unfortunately setting those Lon/Lat's to the bounding params don't seem to do anything. Any insight would be greatly appreciated!

Resources