I am trying to import some GeoJSON to the FeatureGroup in _onFeatureGroupReady event handler, but it doesn't appear to be rendered into the map. The code is mostly based on the example from the library react-leaflet-draw here. Strangely, the edit menu becomes usable, indicating that the data is maybe there, but just not being rendered.
I'm not sure what's happening, as I'm a beginner to maps in general. The relevant code is in the else if(this.props.data) { block. The console.log() statements all show the data being there and in the correct format.
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
37.79,
-122.45
],
[
37.79,
-122.42999999999999
],
[
37.77,
-122.42999999999999
],
[
37.77,
-122.45
],
[
37.79,
-122.45
]
]
]
}
}
]
}
Here is the code where I'm trying to import this data into the FeatureGroup:
_onFeatureGroupReady = (ref) => {
console.log('_onFeatureGroupReady');
console.log(ref);
if(ref===null) {
return;//bug???
}
this._editableFG = ref;
// populate the leaflet FeatureGroup with the geoJson layers
if(this.state.data) {
console.log('importing service area from state');
let leafletGeoJSON = new L.GeoJSON(this.state.data);
let leafletFG = this._editableFG.leafletElement;
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
}else if(this.props.data) {
console.log('importing service area from props');
this.setState({data:this.props.data},()=>{
console.log(this.state.data);
let leafletGeoJSON = new L.GeoJSON(this.state.data);
console.log(leafletGeoJSON);
let leafletFG = this._editableFG.leafletElement;
console.log(leafletFG);
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
})
}
}
What might I be doing wrong (or even better, any way I can achieve this)?
Hope this will help you.First,it's not recommended to use this.setState in _onFeatureGroupReady,it will lead to multiple render in map.May be transfer it to componentDidMount which is invoked before the map rendered.And about the return in _onFeatureGroupReady,it's not exactly a bug, but it will return undefined.
_onFeatureGroupReady = (ref) => {
console.log('_onFeatureGroupReady');
console.log(ref);
if(ref===null) {
return;
}
this._editableFG = ref;
// populate the leaflet FeatureGroup with the geoJson layers
if(this.state.data) {
console.log('importing service area from state');
let leafletGeoJSON = new L.GeoJSON(this.state.data);
let leafletFG = this._editableFG.leafletElement;
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
}else if(this.props.data) {
console.log('importing service area from props');
console.log(this.state.data);
let leafletGeoJSON = new L.GeoJSON(this.state.data);
console.log(leafletGeoJSON);
let leafletFG = this._editableFG.leafletElement;
console.log(leafletFG);
leafletGeoJSON.eachLayer( layer =>leafletFG.addLayer(layer));
}
}
Then,about the Map.The latitude and longitude in coordinates of center and coordinates are opposite.So ,maybe the coordinates you set in getGeoJson() is wrong.
<Map center={[37.79,-122.45]} zoom={13} zoomControl={false}>
<FeatureGroup ref={ (reactFGref) => {this._onFeatureGroupReady(reactFGref);} }>
...
</FeatureGroup>
</Map>
function getGeoJson():
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-122.45,
37.79
],
[
-122.42999999999999,
37.79,
],
[
-122.42999999999999,
37.77
],
[
-122.45,
37.77
],
[
-122.45,
37.79
]
]
]
}
}
And,here is my result.
Related
I have two JSON data sources:
Source Data 1:
{
"result": [
{
"resource_list": "7961b907db9253045fbdf1fabf9619d4,55617907db9253045fbdf1fabf9619d2",
"project": "11216",
"project_manager": {
"value": "55617907db9253045fbdf1fabf9619d2"
}
}
]
}
Source Data 2:
{
"result": [
{
"sys_id": "7961b907db9253045fbdf1fabf9619d4",
"email": "test.user1#mysite.com"
},
{
"sys_id": "55617907db9253045fbdf1fabf9619d2",
"email": "test.user2#mysite.com"
}
]
}
I want to reference "resource_list" and "project_manager" from Source Data 1 to "sys_id" in Source Data 2 and get "email" out from Source Data 2 and then compose a final Output like below:
Output:
[
{
"__metadata":
{
"uri": "ProjectCode"
},
"externalProject": "11216",
"projectCodeAssignment":
[
{
"__metadata":
{
"uri": "projectCodeAssignment"
},
"externalProjectAssignee": "test.user1#mysite.com"
},
{
"__metadata":
{
"uri": "projectCodeAssignment"
},
"externalProjectAssignee": "test.user2#mysite.com"
}
]
}
]
Is this possible to get this done entirely in Logic App without using Function App or anything to perform it rather.
I write a js script for you. For a quick demo, I omitted some data related to __metadata, seems that is some hard code, not so important here. Try Logic below:
Code in JS code action:
var body = workflowContext.trigger.outputs.body
var data1 = body.data1;
var data2 = body.data2;
var result = [];
data1.result.forEach(item =>{
var resultItem = {};
resultItem.externalProject = item.project;
resultItem.projectCodeAssignment =[];
var resourceIds = item.resource_list.split(',');
resourceIds.forEach(id =>{
var user = data2.result.find( ({ sys_id }) => sys_id === id );
resultItem.projectCodeAssignment.push({"externalProjectAssignee": user.email})
});
result.push(resultItem);
})
return result;
Request Body(your 2 data set are named as data1 and data2 here ):
{
"data1": {
"result": [{
"resource_list": "7961b907db9253045fbdf1fabf9619d4,55617907db9253045fbdf1fabf9619d2",
"project": "11216",
"project_manager": {
"value": "55617907db9253045fbdf1fabf9619d2"
}
}
]
},
"data2": {
"result": [{
"sys_id": "7961b907db9253045fbdf1fabf9619d4",
"email": "test.user1#mysite.com"
}, {
"sys_id": "55617907db9253045fbdf1fabf9619d2",
"email": "test.user2#mysite.com"
}
]
}
}
Result:
I have a question about this JSON. How to get coordinates from here?
I try to use for(){} like code below but doesn't work.
item {
"type": "type1",
"features": [{
"type": "typeee1",
"geometry": {
"type": "Point",
"coordinates": [
-19.726330999999998,
41.360610000000001
]},
"properties": {
"id_strada": "1433",
"nome_strada": "test3",
} },
{
"type": "typeee2",
"geometry": {
"type": "Point",
"coordinates": [
19.726344999999998,
26.36063
] },
"properties": {
id_strada": "13",
"nome_strada": "test5",
} },
{
"type": "typeee3",
"geometry": {
"type": "Point",
"coordinates": [
19.726358999999999,
98.36065
] },
"properties": {
id_strada": "14",
"nome_strada": "test34",
} }, {
"type": "typeee5",
"geometry": {
"type": "Point",
"coordinates": [
19.726372999999999,
55.360669999999999
] },
"properties": {
id_strada": "14335",
"nome_strada": "test39",
} }],
"last_update": "15-08-2019 15:04:45"
}
function that call JSON is like below.
item: Item[];
this.ws.getitems().subscribe(
item => {
this.item = item;
console.log('this.item.length', this.item.length)
for (let i = 0; i < this.item.length; i++) {
}
}
);
this.item.length is undefined
My question is, how to get coordinates in here?
Can you ask me any idea please?
Thanks!
You don't have an array in an array in an array. You have an array in an object in an object in an array in an object.
interface Feature {
type: string;
geometry: {
type: string;
coordinates: [ number, number ];
};
properties: {
id_strada: string;
nome_strada: string;
};
}
interface Item {
type: string;
features: Feature[];
last_update: string;
}
const items$: Observable<Item> = this.ws.getItems();
const coordinates$: Observable<[number, number]> = items$.pipe(
switchMap((item: Item) => of(
...item.features.map((feature: Feature) => feature.geometry.coordinates)
)),
);
coordinates$.subscribe((coordinates: [number, number]) => console.log(coordinates));
It is really unclear exactly what your intention is here. Your Item object has multiple coordinates within it. Do you intend to link all of the coordinates, or just the first, or do you want to split them by feature? I've provided you a way to just have an unlinked stream of all coordinates you ever receive. You'll have to figure out what it is you want to do with that.
If you were already in item, coordinates are at item.geometry.coordinates
If your supplied json was x, you could get the first coordinates at x.features[0].geometry.coordinates.
You could find each set of coordinates with:
x.features.forEach(item => {
let coords = item.geometry.coordinates
// do something with coords
})
I'm building a small react app with Leaflet and React for showing different metro stations for Vienna.
The problem I came to was how to edit the colors for individual metro lines in react-leaflet. Image of the map with different metro lines.
Now they are all in red, I would like to customize the colors with the colors of the circles.
The colors, name and the coordinates of each metro station are edited in the GeoJSON file.
GeoJSON file (vienna_metro_lines_byLines.geojson)
{
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "id": "01", "properties": { "name": "U1", "color": "red" },
"geometry": { "type": "MultiLineString", "coordinates":
[
[ 48.1423652, 16.3999045 ], [ 48.1458145, 16.3856390 ], [ 48.1537071, 16.3824464 ],
]
}
},
{ "type": "Feature", "id": "02", "properties": { "name": "U2", "color": "#9933ff" },
"geometry": { "type": "MultiLineString", "coordinates":
[
[ 48.2262470, 16.5084951 ], [ 48.2345713, 16.5044830 ], [ 48.2334553, 16.4854766 ],
]
}
Component file
//data
import geojsonDataByLines from './vienna_metro_lines_byLines.geojson';
//main component
class ViennaPoliLynes extends Component {
constructor() {
super();
this.state = {
geojsonDataByLines: geojsonDataByLines
};
}
polylineLineMaker() {
const geojsonDataByLines = this.state.geojsonDataByLines;
const testMe = geojsonDataByLines.features.map((cord) => {
return cord.geometry.coordinates;
});
return testMe;
}
polylineLineColor() {
//The color for the polylines shoud go here
const geojsonDataByLines = this.state.geojsonDataByLines;
const testMe = geojsonDataByLines.features.map((cord) => {
return cord.properties.color;
});
console.log(testMe)
return testMe;
}
render() {
return (
<Polyline positions={this.polylineLineMaker()} color={this.polylineLineColor()}>
</Polyline>
);
}
}
Ty. For your time.
It seems like you are actually creating just one polyline by merging the coordinates of all polylines together. You should try rendering multiple polylines like so:
import {Map, Polyline} from 'react-leaflet'
//data
import geojsonDataByLines from './vienna_metro_lines_byLines.geojson';
//main component
class ViennaPoliLynes extends Component {
render() {
return (
<Map>
{geojsonDataByLines.features.map((feature) => (
<Polyline
positions={feature.geometry.coordinates}
color={feature.properties.color}
/>
)}
</Map>
)
}
}
How to convert coordinates from Leaflet coordinate system to coordinate system that Google uses (WGS-84?), if the data are in an external file (geojson)?
In example with external geojson file, I've defined coordinates for Paris and Zagreb and I'm looking for solution to transform these coordinates to accurate location :)
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": "par",
"properties": {
"name": "Paris"
},
"geometry": {
"type": "Point",
"coordinates": [
48.858093,
2.294694
]
}
},
{
"type": "Feature",
"id": "zg",
"properties": {
"name": "Zagreb"
},
"geometry": {
"type": "Point",
"coordinates": [
45.815399,
15.966568
]
}
}
]
}
There is Proj4js JavaScript library, but I cannot find similar example for this case (with external file).
Your GeoJSon can be used directly by Leaflet without converting the lat/lng.
I use google maps to get GPS lat/lng of some point and use them in Leaflet without conversion.
// Edit
For me Leaflet and Google maps use the same projection.
//EDIT 2
Html :
<div id="map" class="leaflet-container leaflet-fade-anim"></div>
JS :
var map=L.map( "map" ,{
center:[0,0],
zoom:1, minZoom: 1 , maxZoom:18
});
var base_maps = [];
var layer_OSM = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
noWrap: true,
// continuousWorld: true,
attribution: '© OpenStreetMap contributors',
unloadInvisibleTiles: true
});
base_maps['OpenStreetMap'] = layer_OSM;
map.addLayer(layer_OSM);
var markersLayer = new L.FeatureGroup();
var marker = L.marker([p_lat, p_lon]);
markersLayer.addLayer(marker);
map.addLayer(markersLayer);
Is it possible to define your own marker icons in GeoJSON?
I have tried many ways to get the desired effect but nothing works ..
Example code from geojson FeatureCollection where i want add custom icon:
{
"type": "Feature",
"id": "Point1",
"properties": {
"name": "Last point"
},
"geometry": {
"type": "Point",
"coordinates": [22.57031047873893, 51.25080964529834]
}
}
MapBox has created a CustomMarker plugin for Leaflet that should do the trick.
And another great example from Mapbox, GeoJSON Custom Markers and Style
Here's some sample code from that site:
var geoJsonData = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"fillColor": "#eeffee",
"fillOpacity": 0.8
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[119.2895599, 21.718679],
[119.2895599, 25.373809],
[122.61840, 25.37380917],
[122.61840, 21.71867980],
[119.2895599, 21.718679]
]
]
}
}, {
"type": "Feature",
"properties": {
"marker-color": "#00ff00"
},
"geometry": {
"type": "Point",
"coordinates": [120.89355, 23.68477]
}
}]
};
var geoJson = L.geoJson(geoJsonData, {
pointToLayer: L.mapbox.marker.style,
style: function(feature) { return feature.properties; }
}).addTo(map);
NOTE: This is not part of the core LeafletJS library, it requires mapbox.js (and mapbox.css)
If you update to the latest version (at time of writing) the pointToLayer callback in your geojson object will start to work. It doesn't seem to be implemented in 0.7.7 but is currently available on master and I assume it will be in 0.8+.
If you just assign a geoJSON definition to your scope's geojson property with the function present leaflet will render it properly now.