Error when trying to set zoom using SceneView - javascript

Using esri-loader, when trying to create a SceneView using the following the view is not calculating the zoom correctly and I'm getting the following errors in the console:
[esri.views.3d.support.cameraUtils] #zoomToScale() Cannot compute scale from zoom without a tiling scheme
client-hook-3.js:1 [esri.views.3d.state.ViewStateManager] #zoom= Invalid zoom 3
let map = new WebMap({
portalItem: {
id: MAP_ID_HERE
}
});
let view = new SceneView({
container: "map",
viewingMode: "local",
map: map,
zoom: 3
});
Does anyone happen to know what is causing this? Looking through the documentation for SceneView it seems this should be valid in the constructor.

I think in this particular case, using a web map as the map, you have to wait for the view to load in order to set the zoom level. If not it will not be able to calculate the scale, that is the cause of the error.
This should work,
let view = new SceneView({
container: "map",
map: map,
viewingMode: "local"
});
view.when(function() {
view.zoom = 3;
});
UPDATE: (leave the other code because I think it clarify the problem and the final answer)
Well it seems that is not enough to wait for the view, because the basemap could not load everything. So here you have an alternative that works,
const basemap = Basemap.fromId("dark-gray-vector");
const sceneView = new SceneView({
container: this.$el,
map: new WebMap({
basemap,
}),
center: [US_CENTER.longtitude, US_CENTER.latitude],
viewingMode: "local"
});
basemap.loadAll().then(
() => {
sceneView.goTo({ zoom: 3 });
}
);
In this new solution we actually wait till the basemap loads everything (using loadAll method) an then we set the zoom of the view.
This is the full code in your Map.vue,
<template>
<div />
</template>
<script>
import { loadArcGISModules } from "#deck.gl/arcgis";
const US_CENTER = { longtitude: -98.5795, latitude: 39.8283 };
export default {
name: "Map",
props: {},
mounted() {
loadArcGISModules(
[
"esri/WebMap",
"esri/views/SceneView",
"esri/Basemap",
],
{ css: true }
).then(({ DeckRenderer, modules }) => {
const [WebMap, SceneView, Basemap] = modules;
const basemap = Basemap.fromId("dark-gray-vector");
const sceneView = new SceneView({
container: this.$el,
map: new WebMap({
basemap,
}),
center: [US_CENTER.longtitude, US_CENTER.latitude],
viewingMode: "local"
});
basemap.loadAll().then(
() => {
sceneView.goTo({ zoom: 3 });
}
);
});
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
div {
width: 100%;
height: 100%;
}
</style>

Related

Loading map of mapbox on a function call

I am working with the rendering of Mapbox in Angular framework. Right now the issue what am facing is that I cannot load the map in the browser.
I have defined a function where I've given all the required to load the map and I am calling the function from an HTML div container after validating a condition. The control goes into the function but the error is that it is not identifying the container property of the map.
My HTML code:
<div id="map" style="margin-top: 370px;" *ngIf="result;then loadMap()">
my script:
loadMap(){
this.map=new Map({
container:document.getElementById('map') ,//'map'
style: 'mapbox://styles/mapbox/streets-v11',
center: { lng: -102.380979, lat: 35.877742 },
zoom: 9,
pitch: 20,
attributionControl: false
});
this.map.addControl(
new NavigationControl({
showZoom: true,
showCompass: true
}),
'bottom-right'
);
}
The error that I am facing:
Error: Invalid type: 'container must be a String or HTMLElement.
Error
Also, is it really possible to load map with a function call or am I just wasting my time here?
This is what i've been doing.I cannot give upon ngAfterViewInit because it is required for initialization purpose of the DOM.
export class DashboardComponent implements OnChanges,OnDestroy,AfterViewInit {
#Input() searchResults:SidenavComponent;
private map: Map;
constructor(){ }
ngOnChanges(changes:SimpleChanges){
if(!changes.searchResults){
console.log("Inside if");
console.log(changes.searchResults)
this.ngAfterViewInit()
}
// const preValue=changes['searchResults'].previousValue;
// const curValue=changes['searchResults'].currentValue;
// if(preValue!=curValue){
// this.ngAfterViewInit()
// }
}
ngAfterViewInit(){
this.map=new Map(
{
container:document.getElementById('map'),
style: 'mapbox://styles/mapbox/streets-v11',
center: { lng: -102.380979, lat: 35.877742 },
zoom: 9,
pitch: 20,
attributionControl: false
});
this.map.addControl(
new NavigationControl({
showZoom: true,
showCompass: true
}),
'top-right'
);
}
ngOnDestroy(){
this.map.remove();
}
}
The container property of the map<div id="map"> is available once the statement in *ngIf returns true / has completed. This is not the case as long as your loadMap() has not finished. Therefore you cannot identify the container.
--> The container needs to exist before you make the function call.

why openlayers map not working in vue-cli 3

I have added ol package to my vue-cli project through
npm install ol
but the map doesn't load. there is no error and I just find an empty div in the result source.
here is my code =>
the html part :
<div id="map-container"></div>
the js part :
import 'ol/ol.css';
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZSource from 'ol/source/XYZ';
export default {
name: "page",
data() {
return {
...
}
},
methods: {
initMap: function () {
new Map({
target: 'map-container',
view: new View({
center: [0, 0],
zoom: 2
})
});
},
mounted: function () {
this.initMap();
},
}
NOTE => some where I found that I have to call init function as :
this.$nextTick(function () {
initMap();
})
but it made no difference.
guys, I'm running out of time so pls help me.
thanks everybody who wanna help
It looks like you are missing a TileLayer. Something like this:
new Map({
target: "map-container",
layers: [
new TileLayer({
source: new XYZ({
url: "https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
})
})
],
view: new View({
center: [0, 0],
zoom: 2
})
});

How to open map drawn from a leaflet class as a pop up window or in a new tab?

I have the following lines of code that generates a map, as seen it makes use of leaflet class to render it. Which works just fine, except that I additionally require the map to open as a new pop up window, or in a new tab on clicking anywhere on the map.
Code:-
<script src="https://unpkg.com/leaflet#1.0.1/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.0/leaflet.draw.js"></script>
/* miscellaneous stuff here */
<div class="col-sm-6 col-sm-offset-4">
<leaflet class="showMap" defaults="mappingConfig.defaults" center="mappingConfig.cityCenter" markers="markers" controls="controls"></leaflet>
</div>
How should i go about achieving the same? I've not come across any relevant code examples online, which were helpful to this particular scenario
If, in the template of the modal you have a map with the same id of the map in the main view, and put in a services the map object (to share it between the controllers), you can have same objects in modal and in the view.
angular.module('mymap.services', []).factory('MapServices', function () {
var map ={
center : {
lat: 49,
lng: 34,
zoom: 8
}, defaults : {
zoomControl: false,
attributionControl: true
},
baselayers : {
xyz: {....},
markers:[....]
};
return {
getMap: function () {
return map;
},
}});
Then you can use somethings like:
$scope.$on('leafletDirectiveMarker.map.click', function (event, args) {
$scope.map.center.lat = args.model.lat;
$scope.map.center.lng = args.model.lng;
$scope.valueModal = {};
$scope.valueModal.properties = args.model.properties.properties;
//show modal
$scope.modalPopup.show();
});
Or instead to use markers into the angular-leaflet directive you can create a layer:
leafletData.getMap("map").then(function (map) {
map.invalidateSize();
//resp is the geojson
var geojson = new L.GeoJSON(resp, {
onEachFeature: function (feature, layer) {
layer.on('click', function (e) {
$scope.map.center.lat = feature.geometry.coordinates[1];
$scope.map.center.lng = feature.geometry.coordinates[0];
$scope.feature = feature;
//open a modal
$scope.openLayersModal();
});
}
});
markers.addLayer(geojson);
map.addLayer(markers);
}, function (err) {
console.log('ERROR', err.status);
});
});

markerwithlabel didnt display on google map on meteorjs

markerwithlabel didnt display on google map on meteorjs. I am using dburles:google-maps and markerwithlabel v1.1.9. I cant seem to be able to integrate with dburles:google-maps and i placed markerwithlabel.js in public folder
I have this error
Uncaught TypeError: google.maps.MarkerWithLabel is not a function
GoogleMap.jsx
Map = React.createClass({
propTypes: {
name: React.PropTypes.string.isRequired,
options: React.PropTypes.object.isRequired
},
componentDidMount() {
GoogleMaps.create({
name: this.props.name,
element: React.findDOMNode(this),
options: this.props.options
})
GoogleMaps.ready(this.props.name, function(map) {
var marker = new google.maps.MarkerWithLabel({ <-----------ERROR
position: map.options.center,
map: map.instance,
zoom: 8
})
})
},
componentWillUnmount() {
if (GoogleMaps.maps[this.props.name]) {
google.maps.event.clearInstanceListeners(GoogleMaps.maps[this.props.name].instance);
delete GoogleMaps.maps[this.props.name];
}
},
render() {
return <div className="map-container"></div>;
}
})
Home.jsx
Home = React.createClass({
mixins: [ReactMeteorData],
componentDidMount() {
GoogleMaps.load({key: "AIzaSyAIoRRWbFOLmP4iLXrRmgDmNw0STlKMXqU"})
},
getMeteorData() {
return {
loaded: GoogleMaps.loaded(),
mapOptions: GoogleMaps.loaded() && this._mapOptions()
}
},
_mapOptions() {
return {
center: new google.maps.LatLng(1.3, 103.8),
zoom: 8
}
},
render() {
if (!this.data.loaded) {
return <div>Loading map...</div>
}
const script = document.createElement('script')
script.type = 'text/javascript'
script.src = '/markerwithlabel.js'
document.body.appendChild(script)
return <Map name="mymap" options={this.data.mapOptions}/>
}
})
Finally i get it. its a little dumb just use MarkerWithLabel rather than google.map.MarkerWithLabel because the api doesnt comes from google maps api
GoogleMaps.ready(this.props.name, function(map) {
var marker = new MarkerWithLabel({
position: map.options.center,
map: map.instance,
zoom: 8,
labelContent: "$425K",
})
})

Add an ImageLayer with ionic-leafletjs

I want to add an ImageLayer with the Ionic-leafletjs from calendee. I have the map obj. in the angular $scope
Markers, center and so on are working.
This is not working:
$scope.map = {
layers: {
imageOverlay: {
1: {
imageUrl: 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
imageBounds: [[47.062319, 7.614106], [47.062351, 7.614432]]
}
}
}
This is the ionic-leafletjs-map-demo which I used as ground.

Categories

Resources