I'm using azure map.
What's happening is that I have 2 layers. A layer that have Circles and a layer with polygons.
I have a functionality in which a popup appear when I click on a specific circle.
The issue occur when I add the polygon layer after the circle layer.
It's like the polygon layer is being drawn on top of the circle layer. In which it prevent the popup from appearing when clicking on the circle.
Here's how I'm adding the polygon layer:
showFetchedResultOnMap(facilities) {
const self = this;
if (facilities && facilities.length > 0) {
self.cleanRestrictionLayer();
//Create a data source and add it to the map.
self.datasource = new atlas.source.DataSource();
self.map.sources.add(self.datasource);
//Add a data set to the data source.
self.CleanMap();
//Create a data source and add it to the map.
var datasource = new atlas.source.DataSource();
self.map.sources.add(datasource);
self.map.imageSprite.add(self.chosenCategory, 'assets/svg/' + self.chosenCategory + '.svg')
.then(function () {
facilities.forEach(cat => {
datasource.add(new atlas.data.Feature(new atlas.data.Point([cat.longitude, cat.latitude])));
});
//Add a layer for rendering point data as symbols.
self.map.layers.add(new atlas.layer.SymbolLayer(datasource, self.chosenCategory, {
iconOptions: {
//Pass in the id of the custom icon that was loaded into the map resources.
image: self.chosenCategory,
//Optionally scale the size of the icon.
size: 0.1
}
}));
});
}
}
Anyone have an Idea about how I can fix this??
I'm not seeing a polygon layer in the code you provided. That said, when you add layers to the map, the order in which you add them is the z-index by default. Last one added goes on top. That said, when adding the layer using the map.layers.add function, there is a second parameter you can add in which can be another layer or layer id. When this is specified the layer you are adding will be inserted below that second specified layer. Here is the doc on this: https://learn.microsoft.com/en-us/javascript/api/azure-maps-control/atlas.layermanager?view=azure-maps-typescript-latest#add-layer---layer----string---layer-
Here is a short example:
map.layers.add(new atlas.layers.BubbleLayer(datasource, 'myBubbles'));
map.layers.add(new atlas.layers.PolygonLayer(datasource, 'myPolygons'), 'myBubbles');
Related
I used offset property of linelayer in azure maps but it didn't worked
var polylines = new atlas.layer.LineLayer(datasource2, null, {
strokeColor: 'DarkOrchid',
strokeWidth: ['sqrt',['sqrt',['to-number', ['get', 'count']]]]
,
filter: ['any', ['==', ['geometry-type'], 'LineString'], ['==', ['geometry-type'], 'MultiLineString']],
});
You need to use the atlas.data.Curve class. This class allows you to create a curved line by specifying a set of control points. You can then add this curved line to a data source and render it using a line layer. Here is an example:
//Create a data source and add it to the map.
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
//Create a curved line and add it to the data source.
dataSource.add(new atlas.data.Curve([
[-73.972340, 40.743270],
[-74.004420, 40.756800],
[-74.013530, 40.722300]
]));
//Create a line layer to render the line to the map.
map.layers.add(new atlas.layer.LineLayer(dataSource, null, {
strokeColor: 'DarkOrchid',
strokeWidth: 5
}));
To curve a line there is a couple of options. If you want the line to follow the curvature of the earth, you can calculate the coordinates that form a geodesic path. There is a built-in method of this in the atlas.math namespace called getGeodesicPath. For example:
var line = new atlas.data.LineString([[-74.00667,40.754572],[-42.75286,-22.752037]]);
//Convert the coordinates to create a curved geodesic path.
line.coordinates = atlas.math.getGeodesicPath(line);
//Add line to data source.
datasource.add(line);
I'm using google-map-react (not react-google-maps), and is able to insert polygons by calling a function polygonDraw within my main Component (not using drawingManager). My function polygonDraw can be seen below.
I can immediately delete the newest polygon by adding polygon.setMap(null) inside my polygonDraw function.
But here is the problem:
I can't delete previously added polygons or all polygons. My need is to be able to delete all polygons and do this without dependency on event handlers (like a click event on a polygon).
I tried different approaches, but had no successful implementation, including:
I'm not able to construct a Polygon component that render new google.maps.Polygon({.etc.}) objects (based on state/props).
As I'm able to insert polygons with my polygonDraw function my current thinking for strategy is:
To establish a reference for each added polygon. I tried implementing React references, including Callback refs and using React.createRef. But no success. My polygonDraw is inside the main component, but outside the render. I can't figure out if it's possible to establish and store a reference to each added polygon, so reference.setMap(null) can be called for each. And if it is possible I don't know how to establish the reference (code inside constructor?, code inside polygonDraw?, code inside render including GoogleMapReact?)
Any help/advice is appreciated :-)
polygonDraw = () => {
let polygonCoords = [{lat: this.state.lat, lng: this.state.lng}, {.etc.}, {.etc.}]
const polygon = new google.maps.Polygon({
paths: [polygonCoords],
fillColor: 'rgb(255, 215, 0)',
});
polygon.setMap(this.state.map.map);
}
render() {
return (
<GoogleMapReact
.etc.
></GoogleMapReact>
)}
I don't know if it cuts down to performance issues, but what about saving the polygons into an array.
// You have to create a store (eventually in the state?)
const polygons = [];
polygonDraw = () => {
let polygonCoords = [{lat: this.state.lat, lng: this.state.lng}, {.etc.}, {.etc.}]
const polygon = new google.maps.Polygon({
paths: [polygonCoords],
fillColor: 'rgb(255, 215, 0)',
});
polygon.setMap(this.state.map.map);
// Then use this to save it to the polygons
polygons.push(polygon);
// OR this if you want
polygons.push({identifyer: "foo", polygon});
}
Afterwards you can just filter through the polygons array and delete the polygons you need.
I don't know if this solution will work, but you can give it a try :)
My application shows a map with react-leaflet and uses LayersControl to switch between an OSM TileLayer and HERE TileLayer. The code is as follows:
<LayersControl position="topright">
<LayersControl.BaseLayer
name={this.props.intl.formatMessage({id:'map.normal_map'})}
checked={true}
>
{ tileLayerOSM }
</LayersControl.BaseLayer>
<LayersControl.BaseLayer name={this.props.intl.formatMessage({id:'map.terrain_map'})}>
{ tileLayerHERE }
</LayersControl.BaseLayer>
</LayersControl>
The problema I see is the following: when moving the OSM map, some 'squares' are downloaded from HERE while they are not ready with OSM. See the network trace:
I would like to avoid this behavior, since it is a bit annoying for the user, who see changes in the visualization for a short period of time.
I don't have experience using Leaflet with React, but these is clearly not the desired behaviour.
In Leaflet that (retrive the both base layers at the same time) happens when you add both to the map. Something like:
const accessToken = 'foo';
let osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
const mapbox = 'https://api.mapbox.com/styles/v1/mapbox/basic-9/tiles/256/{z}/{x}/{y}?access_token={accessToken}';
const map = L.map('map').setView([42.2, -8.8], 12);
map.addLayer(osm);
map.addLayer(mapbox); // only one should be added to the map
or directly when instantiating the map:
let map = L.map('map', {
center: [42.2, -8.8],
zoom: 12,
layers: [osm, mapbox] // only one should be added to the map
});
With this kind of baselayers you only must add one to the map and use the layer control to switch between one or the other. When only one is added only the tiles for one of the maps are requested, saving bandwith.
As a "shot in the dark" I will try to make the checked value explicit for all layers. First both as a harcoded false, nothing should be shown in the map. Then one with checked=true harcoded and the other with false, and so on. Probably the trouble is how those attributes are managed.
In Anystock/AnyChart, I want to listen to the point event when the mouse clicks.
So, I added the following code as a script.
anychart.onDocumentReady(function () {
// create data table
var table = anychart.data.table();
// add data
table.addData([
['2015-12-24', 511.53, 514.98, 505.79, 506.40],
['2015-12-25', 512.53, 514.88, 505.69, 510.34],
['2015-12-26', 511.83, 514.98, 505.59, 507.23],
['2015-12-27', 511.22, 515.30, 505.49, 506.47],
['2015-12-28', 511.53, 514.98, 505.79, 506.40],
['2015-12-29', 512.53, 513.88, 505.69, 510.34],
['2015-12-30', 511.83, 512.98, 502.59, 503.23],
['2015-12-31', 511.22, 515.30, 505.49, 506.47],
['2016-01-01', 510.35, 515.72, 505.23, 508.80]
]);
// map loaded data
var mapping = table.mapAs({'open': 1, 'high': 2, 'low': 3, 'close': 4});
// create a stock chart
var chart = anychart.stock();
// add a series using mapping
chart.plot(0).ohlc(mapping).name('ACME Corp. Stock Prices');
// set container id for the chart
chart.container('container');
// initiate chart drawing
chart.draw();
// add a mount event listener - It is fine.
chart.listen('click', function(e){
alert(e);
});
// add a point event listener - It does not work.
chart.listen('pointClick', function(e){
alert(e);
});
});
The mouse event was being raised successfully, but the point event did not work.
How does we add the point event listener into anychart.stock() on AnyChart?
If anyone has a solution already, it would be great if you could share it.
Unfortunately, the current version of AnyStock (8.3.0) doesn't support point related events as basic charts. If you want to show additional information about the point you can show it in the point tooltip using formatter function - https://api.anychart.com/anychart.core.ui.Tooltip#format
I am working on a RN app and I have an issue regarding the rotation and dimensions of the screen. I have a gallery application where I show three images in a row if the screen is vertical. I adjust it by dividing the width by the size of the image, I think this way of specifying the number of images in a row makes it consistent and changeable for different devices. However, after I rotate the screen, I was expecting to see more images in a row, but I didn't. I realized the width didn't change, so I saw three images again instead of 5 or 6. I am not sure if the way I am doing this is right or wrong. Any suggestions regarding this?? Also, how can I change the width and height dynamically, so that I can change the aligning of my gallery after rotation?
here is a part of my code
...var {height, width} = Dimensions.get('window');
var imageSize = 120;
// number : number of images in a row
var number = Math.round(width/imageSize);
console.log(number);
var CameraRollView = React.createClass({
propTypes: propTypes,
getDefaultProps: function(): Object {
return {
groupTypes: 'SavedPhotos',
batchSize: 5,
imagesPerRow: number,
assetType: 'Photos',
renderImage: function(asset) {
//var imageSize = 120;
var imageStyle = [styles.image, {width: imageSize, height: imageSize}];
return (
<TouchableHighlight onPress={
()=>{
/**fire gallery action selectImage*/
this.selectImage(asset.node.image.uri, this.images);
}
} key={asset.node.image.uri}>
<Image
source={asset.node.image}
style={imageStyle}
/>
</TouchableHighlight>
);
},
};
},
...
here what important is -imagesPerRow- I want it to be dynamic, as I rotate the device.
I would recommend against using the Dimensions module if you need to respond to screen size changes.
The View component provides an onLayout property that is called each time that View's layout has to be recalculated (e.g. on device rotation). I don't know anything about the architecture of your app, so I will just say the easiest way to use it in my opinion is to set it to a function on the root View in your app that writes the new parameters to state (or to your flux/redux stores if you use that).
You can then pass that information through your app and use it as you see fit.