I am using Esri web with javascript to create a heat map of tracts.
There are groups of tracts that represent one area so I want to merge and remove the bounders between them.
How can I do this?
This is How I draw the tracts:
var featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_Census_Tract_Areas_analysis_trim/FeatureServer/0",
outFields: ["*"],
renderer: renderer,
definitionExpression: "FIPS IN (" + fips + ")"
});
Well, It seems clear that your want to create one large polygon out of too many small polygons(group of tracts).
Follow below steps to achieve this-
don't add feature layer on the map
Create an empty map with basemap and add a graphics layer on it.
query the group of tracts from the layer using esri query task and store the geometry in an array.
use esri gemetryEngine union method and pass the array to it.
union will return a big ploygon without the inner boundaries of 'group of tracts'.
create an esri graphics with new polygon symbol and union polygon geometry.
Add that graphics to the previously added graphics layer.
Feel free to shoot your further queries.
Hoping this will help you :)
Related
Based on: Dim/Hide rest of map around country with leaflet.js
While the accepted answer was almost spot on, its JSFiddle demo only works for old single polygon GeoJSON. Modern multipolygon GeoJSON allows for additional shapes to make up for overseas territories etc., and thus also introduces extra arrays which the JSFiddle demo doesn't know how to handle:
// transform geojson coordinates into an array of L.LatLng
var coordinates = france.features[0].geometry.coordinates[0];
var latLngs = [];
for (i=0; i<coordinates.length; i++) {
latLngs.push(new L.LatLng(coordinates[i][1], coordinates[i][0]));
}
L.mask(latLngs).addTo(map);
I realize this is all basic JavaScript and array 101 stuff, but would anyone happen to know how to make the above code work with the additional arrays from multipolygonal GeoJSON?
Multipolygon example from https://geojson-maps.ash.ms/: https://jsfiddle.net/uc81esy5/
Single polygon example used in the accepted answer: https://jsfiddle.net/r9m4t3d7/
I guess that by "modern GeoJSON" you mean "GeoJSON features of type Polygon with an outer ring but also with inner rings". So this is really about "How do I convert a GeoJSON multipolygon geometry to an array (rings) of arrays (points in a ring) of arrays (Leaflet LatLngs)?".
Please note that the concept of polygons with inner rings is by no means "modern": it does appear in the (now deprecated) 2008 GeoJSON specs, which in turn take heavy inspiration from OGC's Simple Features which date back to 2003.
I would leverage the coordsToLatLngs static method of L.GeoJSON already implemented by Leaflet. e.g.:
var latlngs = L.GeoJSON.coordsToLatLngs(feature.geometry.coordinates, 1);
Remember to perform a sanity check on geometry.type if neccesary; the levelsDeep parameter shall be 0 for LineStrings, 1 for MultiLineStrings and Polygons, and 2 for MultiPolygons.
I have to use OpenLayers to create a logic that draws two Features.
After the user draws Feature A,
We need logic to draw Feature B that surrounds the Feature A outside.
Draw Feature A on a map.
After Feature A is drawn, the system must create Feature B that surrounds Feature A.
The final result should be the same as Image.
PRECONDITION
Feature can have 3 - 6 angles.
The length of each side is unpredictable.
The angle of each side is unpredictable.
All sides of Feature B must be made from all sides of Feature A with the distance specified by the user.
How do we solve this problem?
full source code : https://github.com/JeahaOh/OpenLayersStudy/tree/master/Examples/EffectiveRange/CDN
Hey this looks like creating a geometry with a buffer of x (x is defined by the user).
You can use JSTS to create buffers from a geometry and then map it back to an openlayer geometry.
OpenLayers example that draws geometries with a buffer. This example uses LineString geometries but you can use any geometry.
Looking at your example you probably want sharp edges on your outer geometry so you can use a mitre line join style
var bufParams = new jsts.operation.buffer.BufferParameters();
bufParams.setJoinStyle(
jsts.operation.buffer.BufferParameters.JOIN_MITRE)
var outer = inner.buffer(spacing, bufParams);
See docs for BufferParameters for more options.
Here is a jsfiddle that shows it.
Currently I am working on Openlayers 3.
I used custom overlays in Google maps Javascript api v3 to add customized markers as html div on the map. And these markers are grouped and plotted in different custom overlays.
Now I am trying to implement the same in OpenLayers 3, but I couldn't find any solution as the overlays in OpenLayers 3 takes one marker in one overlay.
Can I group overlays in OpenLayers 3 in order to group the markers? Or Is there any other options available?
You have multiple possible options.
A) If you have only one dataset, then you could use a StyleFunction. See this ol3 vector example, more specifically this section of code:
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: 'https://openlayers.org/en/v3.20.1/examples/data/geojson/countries.geojson',
format: new ol.format.GeoJSON()
}),
style: function(feature, resolution) {
style.getText().setText(resolution < 5000 ? feature.get('name') : '');
return style;
}
});
See the style property? It can be a ol.style.Style or a style function, like demonstrated above. The function receives the feature and current resolution of the map view as argument and is called every time the feature gets rendered (or re-rendered). Returning a ol.style.Style or array of style objects will render the feature using the/these styles.
The feature can have unique properties, i.e. feature.getProperties(). Using as many properties within the feature(s), you can return a unique array of unique style objects.
Here's a more complex ol3 example featuring style functions that you can look and have an example of dynamic styling depending on the resolution. That could give you a better idea of what you could do with the feature properties.
B) If you have multiple datasets, then you can create one vector layer per dataset and define a unique style object on the layer, which would render the features all the same.
I have a map with a few base layers. Users can choose the base layer and then save the map. After saving the map, the system loads it with the new base layer. That base layer should be selected in the L.Control.Layers control. However, there's no way in the API to select a base layer.
Anyone knows a way around this, or a different plug in?
UPDATE: Here is the code I use. MapConfigs has the ids in MapBox, and can create the map that L.control.layers requires.
var map = L.mapbox.map( components.mapDivId , MapConfigs.idFor(baseLayerName) );
map.addControl( L.control.layers(
MapConfigs.toBaseLayersControlMap(map)
).setPosition("topright"));
Thanks!
Why not store references to all the base layers available in a hash, then use addLayer or removeLayer (http://leafletjs.com/reference.html#map-addlayer) as needed to programmatically select base layers?. Something like below.
var tileLayers = {light: L.tileLayer('lightUrl'),dark: L.tileLayer('darkUrl')}
I have to allow a user to input multiple zip codes, retrieve the latitude and longitude from a database and then build a huge polygon that encompasses them.
I'm coding in Java and using Google Maps API V3. I have no problem doing a single zip code build. But upon adding more zip codes the polylines that are generated go hay-wire and distort the polygon, as pictured below.
What do I need to change in my code to make all these smaller polygons into one larger one? I've scoured Google for answers and all I've managed to come across is building each zip code's polygon individually but that still won't give me a end result of a larger, single polygon.
Currently, after the zip codes are inputted the program collects the lat and long points from the database and feeds them into a giant array of arrays (a String[][] to be exact), which is then passed the the html and javascript to generate the resulting polygon.
My javascript is highly similar to the GoogleMaps API V3 simple polygon example:
function clearHello(coords1){
coords = coords1
var triangleCoords = new Array();
var l = coords.length;
for (var x = 0; x < l; x++){
triangleCoords[x] = new google.maps.LatLng( coords[x][0], coords[x][1]);
}
// Construct the polygon.
bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
bermudaTriangle.setMap(document.map);
Suggestions? Is there a code technique out there that will take my giant array and then remove the interior points that appear to be the cause of this distortion?
EDIT: Wondering about a different approach, does anyone know of a way to remove the interior lines that creating the bizarre trapezoid thing so that the zipcode polygon can fill in properly? I know I can make them transparent, but that doesn't stop the distortion of the polygon. Also simply managing it as a few polygons that I populate won't work as this program needs to be able to handle up to 200 zip codes worth of coordinates at a time.
It sounds like you're wanting to remove shared boundaries and create a kind of macro object. In the land of Geographic Information Systems (GIS), this sort of operation is called known as "Dissolve". You can combine two 3rd-party libraries to do what you want exclusively in JavaScript code.
How to do a GIS Dissolve in JavaScript
You can combine both the Wicket and the JavaScript Topology Suite (JSTS) libraries to perform a Union/Dissolve operation and derive a single polygon geometry with a united outer boundary.
In simple terms, Wicket will handle going to and from your Google Maps Polygon objects to Well Known Text (WKT) geometry expressions, and the JSTS can then do a union/dissolve operation using the WKT.
Preliminary steps: Download the two libraries and reference them in your project.
1) First download the JSTS library, unzip it, browse into the lib folder, and include the two lib files (javascript.util.js, and jsts.js) in your project. I copied mine into a separate jsts folder and referenced them in my project like this..
<script type="text/javascript" src="jsts/javascript.util.js"></script>
<script type="text/javascript" src="jsts/jsts.js"></script>
2) Next download the Wicket library, unzip it, and include wicket.js and wicket-gmap3.js in your project. Similarly, I copied mine into a separate wicket folder and referenced them like this..
<script type="text/javascript" src="wicket/wicket.js"></script>
<script type="text/javascript" src="wicket/wicket-gmap3.js"></script>
Use Wicket to get the Polygon WKT geometries, then use JSTS to perform a Dissolve operation.
3) Unite these two libraries to get Well Known Text geometries from Wicket, and perform a Dissolve operation with JSTS.
My demo assumes two Google polygon objects were already instantiated and were passed into the method—polygon1 and polygon2. Obviously this is intended to be a simple example, so you'll need to modify it for more elaborate operations.
function DissolveTwoGeometriesWithJSTS(polygon1, polygon2)
{
// Instantiate Wicket
var wicket = new Wkt.Wkt();
wicket.fromObject(polygon1); // import a Google Polygon
var wkt1 = wicket.write(); // read the polygon into a WKT object
wicket.fromObject(polygon2); // repeat, creating a second WKT ojbect
var wkt2 = wicket.write();
// Instantiate JSTS WKTReader and get two JSTS geometry objects
var wktReader = new jsts.io.WKTReader();
var geom1 = wktReader.read(wkt1);
var geom2 = wktReader.read(wkt2);
// In JSTS, "union" is synonymous with "dissolve"
var dissolvedGeometry = geom1.union(geom2);
// Instantiate JSTS WKTWriter and get new geometry's WKT
var wktWriter = new jsts.io.WKTWriter();
var wkt = wktWriter.write(dissolvedGeometry);
// Reuse your Wicket object to ingest the new geometry's WKT
wicket.read(wkt);
// Assemble your new polygon's options, I used object notation
var polyOptions = {
strokeColor: '#1E90FF',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#1E90FF',
fillOpacity: 0.35
};
// Let wicket create a Google Polygon with the options you defined above
var newPoly = wicket.toObject(polyOptions);
// Now I'll hide the two original polygons and add the new one.
polygon1.setMap(null);
polygon2.setMap(null);
newPoly.setMap(map);
}
Here's what basically happened. Before executing the code..
and after..
You can try topojason javascript. A good start is also a concave hull. I have wrote a concave hull php class # phpclasses.org. It takes a set of points and find the concave hull with the concave hull algorithm. Basically it's a delaunay triangualation and you delete the longest edges. You can also read my answer here:Calculate bounding polygon of alpha shape from the Delaunay triangulation.
The solution is to use GeoJson to represent what you want and there is a API for that, so you don't have to worry about the backend or any distortion in the polygon(s), as pictured below.:
here: www.boundaries-io.com
example query:
/rest/v1/public/boundary?zipcode=30044,30043,30045'
you can also query for multiple counties,cities,etc in one line of code.
simple in java script:
https://developers.google.com/maps/documentation/javascript/datalayer#sample_geojson
...
map.data.loadGeoJson('.../rest/v1/public/boundary?zipcode=30044,30042,30045'');
...
results gives this, with additional queryable information per zipcode:
*****I do work for the company*