I'm working on a map that uses FeatureLayer.Mode_ONDEMAND. To see certain layer, I pass in a project ID using featureLayer.setDefinitionExpression. Where such layer exists, I see it. What I want to know is how to detect when no layer exists. I want to print an alert to the viewer instead of showing just a blank map. Here's my code:
function init() {
map = new esri.Map("mapDiv", {
basemap: "topo",
zoom: 9
});
var featureLayer = new esri.layers.FeatureLayer("http://services.arcgis.com/v01g34asdwfAi/arcgis/rest/services/Projects/FeatureServer/0",{
mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
outFields: ["*"],
opacity: 1
});
featureLayer.setDefinitionExpression("SrvyDescID=\'' . htmlspecialchars($ProjectID) . '\'");
console.log(featureLayer.graphics);
console.log(featureLayer.graphics[0]);
map.addLayer(featureLayer);
}
What I learned is when the project is valid, feature.graphics will return an array. But I'm unable to treat it like an array. For example:
console.log(featureLayer.graphics) returns an array object
but
console.log(featureLayer.graphics[0]) returns "undefined".
featureLayer.graphic.length also doesn't work. How do I use this array object to let me know that a layer is displayed on the map?
Attached is a screenshot of the console log. Thanks for your help.
I needed to catch "update-end" event. Final code:
map = new esri.Map("mapDiv", {
center: [-118.30, 34.3],
zoom: 8,
basemap: "topo"
});
on(map, "update-end", function(){ // update-end event will execute after the layer has been added to the map
if(featureLayer.graphics.length >= 1)
{
// do your thing
}
})
var featureLayer = new
esri.layers.FeatureLayer("http://services.arcgis.com/v01gqwMseaqNAi/arcgis/rest/services/Project_boundaries_021616/FeatureServer/0",{
mode: esri.layers.FeatureLayer.MODE_ONDEMAND,
outFields: ["*"],
opacity: 1
});
featureLayer.setDefinitionExpression("SrvyDescID=\'' . htmlspecialchars($SDID) . '\'");
map.addLayer(featureLayer);
Related
I've build a simple Here Map using Vue 2 and the JS API in version 3.1.30.17. The map works fine in all browsers except Firefox v102.
This is the error message in Firefox:
Tangram [error]: Error for style group 'non-collision' for tile 20/7/68/41/7 CanvasRenderingContext2D.drawImage: Passed-in canvas is empty: loadTexture#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:417267
e/sn.addWorker/<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:63015
EventListener.handleEvent*e/sn.addWorker#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:62515
e/value/<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:515089
value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:515502
value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:514847
e/value/this.initializing<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:511497
promise callback*value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:511472
Ul#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:335:441
p.eh#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:378:446
p.Ge#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:329:436
p.Ge#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:376:356
S#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:369:214
T.prototype.u#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:410:166
T#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:401:290
... The error is even bigger
The following method I'm using to init Here Maps inside Vue's mounted:
async initializeHereMap() {
const mapContainer = this.$refs.hereMap;
const H = window.H;
// Initialize the platform object:
this.platform = new H.service.Platform({
apikey: this.apiKey,
});
await this.geocode(this.platform, this.originAddress)
.then(data => this.routingParameters.origin = data[0]);
await this.geocode(this.platform, this.destinationAddress)
.then(data => this.routingParameters.destination = data[0]);
// Obtain the default map types from the platform object
const defaultLayers = this.platform.createDefaultLayers({
lg: window.navigator.language,
});
// Instantiate (and display) a map object:
const map = new H.Map(mapContainer, defaultLayers.vector.normal.map, {
zoom: this.zoom,
center: this.center,
padding: {
top: this.padding,
bottom: this.padding,
left: this.padding,
right: this.padding,
},
});
// create map pins
const mapPinOrigin = this.addMapPin('A', 40);
const mapPinDestination = this.addMapPin('B', 40);
let linestring = new H.geo.LineString();
linestring.pushPoint(this.routingParameters.origin);
linestring.pushPoint(this.routingParameters.destination);
// Create a polyline to display the route:
let routeLine = new H.map.Polyline(linestring, {
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
});
// Create a marker for the start point:
let startMarker = new H.map.Marker(this.routingParameters.origin, { icon: mapPinOrigin });
// Create a marker for the end point:
let endMarker = new H.map.Marker(this.routingParameters.destination, { icon: mapPinDestination });
// Add the route polyline and the two markers to the map:
map.addObjects([routeLine, startMarker, endMarker]);
// Set the map's viewport to make the whole route visible:
map.getViewModel().setLookAtData({bounds: routeLine.getBoundingBox()});
// add behavior control
if (this.behaviors) new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// add UI
if (this.controls) H.ui.UI.createDefault(map, defaultLayers);
},
Is there some one facing the same issue and could solved it?
Did you follow this example on: https://developer.here.com/tutorials/how-to-implement-a-web-map-using-vuejs/ ?
Tangram error is related to rendering e.g. when render map objects (like icons, markers, polylines etc.) and map vector tiles.
I don't think so that this issue related to HERE JS Map API.
Because all examples on https://developer.here.com/documentation/examples/maps-js are working well on my FireFox 102.0.1
It could be some map objects like icons or markers etc. are created in some moment but is not finished yet and then try to push onto map? Creating an icon in some asynchron function?
Or in like your code:
await this.geocode(this.platform, this.originAddress)
.then(data => this.routingParameters.origin = data[0]);
You don't know when func geocode will be finished (e.g. due slow internet connectivity)
It could be this command above is not done yet, but your code is already start to run this code:
linestring.pushPoint(this.routingParameters.origin);<-- 'this.routingParameters.origin' could be null
linestring.pushPoint(this.routingParameters.destination);
// Create a polyline to display the route:
let routeLine = new H.map.Polyline(linestring, { <-- Could cause Tangram error because 'linestring' is strange due undefined origin yet!
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
});
The polyline options is not correct in:
new H.map.Polyline(linestring, {
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
}
Why in above the 'linestring' is second time in options?
Please follow correct syntax on:
https://developer.here.com/documentation/maps/3.1.31.0/api_reference/H.map.Polyline.html#.Options
I am using vue 2.6.10 and I have the following dependencies vue-mapbox 0.4.1 and mapbox-gl 1.3.2
The map works, but I cannot get all the points of the map, create bounds and make the map zoom there.
What I am doing now, based on this and this
In my template
<MglMap
ref="map"
#load="mapLoaded()">
and then in my javascript
import Mapbox from "mapbox-gl";
components: { Mapbox}
methods :{
mapLoaded(){
let coords = [];
//coords is array , contains arrays like [-118.578, 51.524]
let bounds = coords.reduce((bounds, coord)=> {
return bounds.extend(coord);
}, this.mapbox.LngLatBounds(coords[0], coords[0])
);
this.$refs['map'].map.fitBounds(bounds, { padding: 20 });
}
},
created(){
this.mapbox = Mapbox;
}
This should work, but I keep getting
TypeError: this.setSouthWest is not a function
so I guess there is a problem in this.mapbox.LngLatBounds(coords[0], coords[0]) , maybe the this.mapbox. or the LngLatBounds does not work.
If I console log the coords[0], prints an array [10.467778, 37.600833]
What am I missing? Thanks
I have got the same error. Turns out I have missed "new" keyword.
You can try adding the "new" keyword for "this.mapbox.LngLatBounds"
The following code worked for me.
import mapboxgl from 'mapbox-gl';
Vue.prototype.$maps = mapboxgl
this.map = new this.$maps.Map({container: 'mapContainer', // container ID
style: 'mapbox://styles/mapbox/streets-v11', // style URL
zoom: 9 // starting zoom
});
const sourceMarker = new this.$maps.Marker().setLngLat(origin).addTo(this.map);
const destMarker = new this.$maps.Marker().setLngLat(destination).addTo(this.map);
const bounds = new this.$maps.LngLatBounds(origin, destination);
this.map.fitBounds(bounds);
I have a GmapMap component in my Vue site and would like to display the traffic on the map with a traffic layer that can be toggled on or off.
The following gives me the terrain layer activated, but I don't see the traffic layer.
<GmapMap ref="baseMap" map-type-id="terrain" >
...
</GmapMap>
This is how you implement it in the normal non Vue way:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 13,
center: {lat: 34.04924594193164, lng: -118.24104309082031}
});
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
}
Thanks to #Antonio I got this to work. It now displays the traffic all the time, so if anybody has a way to toggle the layer please let me know.
mounted() {
this.$refs.baseMap.$mapPromise.then(map => {
const trafficLayer = new google.maps.TrafficLayer()
trafficLayer.setMap(map)
})
}
I am using vuejs as my frontend framework and esri-loader to load arcgis js 4.11 in vue.I am beginner in arcgis js api and trying to use SketchViewModel to draw a polygon. However, when I use create() function, I am getting sketchVM.create is not a function as error.
I followed arcgis js 4.11 SketchViewModel's documentation
I have divided the code for arcgis js in two methods:- one method is responsible for loading map and view, and another is used to draw polygon.
views/mapView.vue
<script>
...
draw(){
loadModules(
[
"esri/layers/GraphicsLayer",
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/geometryEngine"
],
{
url: "https://js.arcgis.com/4.11/" // use a specific version
}
).then(
([
SketchViewModel,
geometryEngine,
GraphicsLayer
]) => {
console.log("Area section active")
this.view.surface.style.cursor = "crosshair"; // change cursor style to crosshair
this.graphicsLayer = new GraphicsLayer();
// needed to sketch polygon
var sketchVM = new SketchViewModel({
layer: this.graphicsLayer, // graphics layer over which polygon will be added
view: this.view, // view where polygon will be rendered
updateOnGraphicClick: true, // to allow graphic updation on through click event
defaultUpdateOptions:{
tool:'reshape', // this will set reshape as default tool for update event
},
polygonSymbol: { // style and type for polygon symbol
type: "simple-fill",
color: "rgba(138,43,226, 0.8)",
style: "solid",
outline: {
color: "white",
width: 1
}
}
});
sketchVM.on("create", (event)=>{
if(event.state === "complete"){
console.log(geometryEngine.planarArea(this.graphicsLayer.graphics.items[0].geometry, "square-meters"))
}
});
sketchVM.on("update", (event)=>{
// if() // event to remove graphic on pressing delete key
console.log("Updated value state : ",event.state)
});
console.log("drawing mode on")
sketchVM.create("polygon", {mode:"click"}); // getting error at this line
console.log("draw view returned")
return this.view;
}
);
},
...
</script>
I am trying to add click events on the graphs that I am rendering. From chart.click to chart.on('click', function (e){ }).
What I am trying to do is allow the user to select points on the graph and for me to now what selections the user made. Is that at all possible using chartist.js?
I read through the documentation: CHARTIST.JS
My code:
if (item.GraphType.Description == "Line") {
var chart = new Chartist.Line(
container[0],
{
labels: d.Labels,
series: d.SeriesData
},
{
axisY: {
offset: 60
}
}
);
chart.click(function (e) {
console.log(e);
});
}
It is entirely possible, yes. Chartist renders SVG nodes to the page, so using a library like jQuery you can easily find all nodes that you want and attach events to them. You can be as specific or broad in the nodes you're looking for to only attach events to very specific nodes or elements on the chart.
For completeness sake, here is a short example of how to attach events that log the value of a data point when clicked upon to the console using jQuery:
$('.ct-chart-line .ct-point').click(function () {
var val = $(this).attr("ct:value");
console.log(val);
});
You should, however, make sure that the events attach only when the chart is created or drawn if you want to ensure the data points are on the page, which can be triggered by the "created" or "draw" events:
var chart = new Chartist.Line(...);
// attach an event handler to the "created" event of the chart:
chart.on("created", function () {
// attach the necessary events to the nodes:
$('.ct-chart-line .ct-point').click(function () {
var val = $(this).attr("ct:value");
console.log(val);
});
});