I need to create a layout with a "menu" sort of thing on the left, and on the right load a the world map. In the left menu I will have a tree, with checkboxes on the leaves. Each leave is a tile that will be loaded on it's position when the checkbox is selected. Let's say on the tree I have as parents USA and Canada. Under USA I have New York Buildings, New York Streets, Washington Buildings, and under Canada something similar. When I check New York Buildings, I need to load that tile over the map and center the map to that tile. When I click New York Streets I need the other tile to be put over this first one(it will have transparency). And so on. The main idea is that I cannot center the map to the location of the tile. Haven't tried the rest, this is where I am stuck. My code:
#{
ViewBag.Title = "Map";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="mainWindow"
data-dojo-type="dijit.layout.BorderContainer"
data-dojo-props="design:'headline', gutters:false"
style="width:100%; height:100%;">
<div id="header"
data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'">
This is the header section
<div id="subheader">subheader</div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" id="leftPane" data-dojo-props="region:'left'">
<div data-dojo-type="dijit.layout.TabContainer">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Legend', selected:true">
<div id="legendDiv"></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Tab 2'" >
Content for the second tab
</div>
</div>
</div>
<div id="map" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div>
<div id="footer" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'bottom'">
this is the footer section
</div>
</div>
#section Head
{
<script type="text/javascript">
var map;
require(["esri/map", "esri/layers/ArcGISTiledMapServiceLayer", "dojo/domReady!"],
function (Map, Tiled) {
var tiled = new Tiled("http://xx.xxx.xx.xx:xxxx/arcgis/rest/services/USA/NewYork_tiles/MapServer");
map = new Map("map", {
basemap: "topo",
center: [[-79.40, 43.64],
zoom: 12
});
map.addLayer(tiled);
}
);
</script>
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title></title>
<link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
<style>
html, body, #map {
height: 100%; width: 100%; margin: 0; padding: 0;
}
</style>
<script src="http://js.arcgis.com/3.8/"></script>
#RenderSection("Head", false)
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body class="claro">
#RenderBody()
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
this is how I found that one centers the map. But I would like to center it to the loaded tile. Also, can the folder structure with the tiles (http://xx.xxx.xx.xx:xxxx/arcgis/rest/services) loaded in a tree?
The map object has several methods for displaying a particular view, be it centring on a MapPoint or other geometry. For example, you could use Map.centerAt(mapPoint) if you had a map point. What you want to do is centre on the extent of the tiled map service you've loaded so you can use map.setExtent(extent, fit) passing it the extent of the tiled service and the Boolean fit if you want it to zoom as required to fit the whole extent. You can get the extent of the tiled service using TiledMapServiceLayer.fullExtent property. For example:
map.setExtent(tiled.fullExtent, true);
You can subsequently put this into your check box event function so that every time it's checked it zooms to the extent (if that's how you want it to behave, another option might be to have the checkbox click event just toggle the layers visibility but then have a 'goto' button next to it that zooms to it).
You can check out more documentiontation for the map object and all of the ArcGIS API here: https://developers.arcgis.com/javascript/jsapi/map-amd.html
Hope this helps.
Edit:
As per your comment, trying to access the fullExtent property straight after the call to load the layer doesn't work because addLayer is asynchronous and so execution returns before the layer is loaded. To set the extent straight as soon as the layer is loaded, you need to register a function to run when the layers onLoad event is raised. The following code should achieve this:
var tiled = new Tiled("http://xx.xxx.xx.xx:xxxx/arcgis/rest/services/USA/NewYork_tiles/MapServer");
tiled.on("load", displayLayerExtent);
map.addLayer(tiled);
function displayLayerExtent(evt) {
map.setExtent(evt.layer.fullExtent, true);
}
Related
I'm using MapBox on my application and i would like to know how can i display lat and lng inside div element after i select an address from a list that are display inside a div? My reference is this MapBox page https://docs.mapbox.com/mapbox-gl-js/example/mapbox-gl-geocoder-no-map/, but i didn't find a correct way to do that using javascript.
To explain more clearly my doubt, below are the code that i'm using on my application and i would like to display lat and lng inside "latitude" and "longitude" div's as below if is possible:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Use the geocoder without a map</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.1/mapbox-gl.css" rel="stylesheet" />
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.min.js"></script>
<link
rel="stylesheet"
href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v4.5.1/mapbox-gl-geocoder.css"
type="text/css"
/>
<!-- Promise polyfill script required to use Mapbox GL Geocoder in IE 11 -->
<script src="https://cdn.jsdelivr.net/npm/es6-promise#4/dist/es6-promise.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise#4/dist/es6-promise.auto.min.js"></script>
<style>
#geocoder {
z-index: 1;
width: 100%;
text-align: center;
top: 20px;
}
.mapboxgl-ctrl-geocoder {
min-width: 100%;
}
</style>
<div id="geocoder"></div>
//How to display latitude and longitude inside div element below after select a value inside geocoder div above?
<div id="latitude">
<div id="longitude">
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiM3dzdG9yZSIsImEiOiJja2RoaWVlaGwyc2VxMnlwbWVrd2F2bmVoIn0.YNjkfQ-709GuxaE4vOjsxg';
var geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
types: 'country,region,place,postcode,locality,neighborhood'
});
geocoder.addTo('#geocoder');
</script>
</body>
</html>
In this case, how can i improve the code above to display latitude and longitude informations inside a div after select a value inside geocoder div?
If I'm understanding you well, what you want is basically capture the result selected in the geocoder and paint the coordinates of the result in a div. For that, you need to subscribe to the result event.
For that, you need to add the event listener like this, and there paint the result in the inner HTML of the div:
geocoder.on('result', function(r) {
console.log(r);
document.getElementById("coords").innerHTML = r.result.center;
})
I have created a fiddle on how to subscribe to result selected on geocoder
PS: If this answer solves your question, please mark it as answer accepted, in that way it will help other users to know is the right solution.
i created buttons to zoom to particular countries. However when i clicked the button,Singapore it navigate to Singapore but i cant see exactly the Singapore country.
So i wanted a better image.
Here is my code below...
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8">
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>My Work</title>
<script src="../Build/Cesium/Cesium.js">
</script>
<style>
#import url(../Build/Cesium/Widgets/widgets.css);
html, body, #cesiumContainer {
width: 98%; height: 98%; margin: 0; padding: 0; overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer">
<button type="button" class="cesium-button" onclick = "zoomToSingapore();" data-toggle="tooltip" data-placement="bottom" title="Please click me if you want to zoom to Singapore">Zoom To Singapore</button>
<button type="button" class="cesium-button" onclick = "zoomToMalaysia();" data-toggle="tooltip" data-placement="bottom" title="Please click me if you want to zoom to Malaysia">Zoom To Malaysia</button>
</div>
<div id="cesiumContainer" style="position:absolute;top:24px;right:24px;width:38px;height:38px;"></div>
<script>
viewer = new Cesium.Viewer('cesiumContainer', {
timeline: false,
navigationHelpButton: false,
infoBox: false
});
function zoomToSingapore()
{
var singapore = Cesium.Cartesian3.fromDegrees(103.851959, 1.290270);
viewer.camera.lookAt(singapore, new Cesium.Cartesian3(0.0, 0.0, 4200000.0));
}
function zoomToMalaysia()
{
var malaysia = Cesium.Cartesian3.fromDegrees(101.9758, 4.2105);
viewer.camera.lookAt(malaysia, new Cesium.Cartesian3(0.0, 0.0, 4200000.0));
}
</script>
</body>
</html>
My question, if i click Singapore, it will zoom to Singapore just like the second image which i have attached to this question.. What do i need to zoom just like the last image???Can you please help me?? Thank you
It looks like your height is too high. Try changing 4200000.0 to 42000.0.
Edit: Here's a more complete code example. This one turns on labels, so you can see the borders. Paste this code into Sandcastle and run it with F8.
var imagery = Cesium.createDefaultImageryProviderViewModels();
var viewer = new Cesium.Viewer('cesiumContainer', {
imageryProviderViewModels: imagery,
selectedImageryProviderViewModel: imagery[1]
});
var height = 50000;
var singapore = Cesium.Cartesian3.fromDegrees(103.85, 1.33, height);
viewer.camera.flyTo({
destination: singapore,
duration: 0
});
Above, I get the default list of imagery providers, and pre-select the one with labels turned on. Then I fly to a point 50km above Singapore, using duration: 0 to snap the camera there.
In the markup below, I want to set the container property of the MapView to the <div> with an Id = "viewDiv". When I remove the outer <div> with the Id = "container" everything works and a map appears. When I run using the outer container <div>, the map does not appear. How do I set the container property to the inner <div>?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Get started with MapView - Create a 2D map</title>
<style>
html, body, #viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.3/esri/css/main.css">
<script src="https://js.arcgis.com/4.3/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"dojo/domReady!"
], function(Map, MapView){
var map = new Map({
basemap: "national-geographic"
});
var viewNode = document.getElementById("viewDiv");
var view = new MapView({
container: viewNode, // Reference to the scene div created in step 5
map: map, // Reference to the map object created before the scene
zoom: 4, // Sets the zoom level based on level of detail (LOD)
center: [15, 65] // Sets the center point of view in lon/lat
});
});
</script>
</head>
<body>
<div id="container">
<div id="viewDiv"></div>
</div>
</body>
</html>
The reason it works if you remove the outter div is because the inner div has a height of 100% of the window. But with the outter div the the inner div has a height of 100% of nothing (the height specified for the outter div). So give the outter div a height.
#container {
height: 100%
}
I am using JQuery mobile with the Google Map API.
The map is not displayed properly unless I refresh the page and I don't understand why.
here is my map.html file:
<div data-role="page" id="map-page">
<div data-role="content" id="canvas-map" style="background-color:red"></div>
<script src="js/map.js"></script>
<script type="text/javascript">
var $canvasMap = $('#canvas-map');
$('#canvas-map').on('pagebeforeshow', initMap());
</script>
</div>
and my map.js file:
function initMap() {
"use strict";
google.maps.visualRefresh = true;
var marker, map,
myLocation = {lat:50, lon:-80},
mapOptions = {
zoom: 5,
center: new google.maps.LatLng(myLocation.lat, myLocation.lon),
mapTypeId: google.maps.MapTypeId.PLAN,
disableDefaultUI: true
};
$('#canvas-map').css("height", "200px").css("padding", "0px");
map = new google.maps.Map(document.getElementById('canvas-map'), mapOptions);
/** MyPosition **/
marker = new google.maps.Marker({
map: map,
draggable: false,
animation: google.maps.Animation.DROP,
position: new google.maps.LatLng(myLocation.lat, myLocation.lon),
});
}
If I navigate from another page to the above page, I get the following result:
And then when I refresh, I get the expected result:
It is obviously not a problem with the canvas, since it is displayed (in red). Plus,if I navigate trhough the map, I can see the marker displayed at the right position.
These screenshots were made using Google Chrome, I tried with Firefox and the canvas is here completely red, no map at all.
PS: this is a simple version of my original code, but the behavior is the same.
EDIT:
See Gajotres' answer for details, but basically, within the link to access map.html page, adding target="_blank" solved the issue. Note that target="_self" seems to work as well, strange since it is supposed to be the default value. Details on target here.
There's a trick how google maps v3 framework can be easily implemented with jQuery Mobile.
Lets talk about the problems here. your content div has a height and width problem, mainly because only time page dimensions can be calculated correctly is during the pageshow event. But even then content div will not cover full page.
Your problem can be solved with a little bit of CSS :
#content {
padding: 0 !important;
position : absolute !important;
top : 40px !important;
right : 0 !important;
left : 0 !important;
height: 200px !important;
}
Basically you are forcing your content to cover available space.
Working example: http://jsfiddle.net/RFNPt/2/
Final solution :
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
<title>MyTitle</title>
</head>
<body>
<div data-role="page" class="page">
<div data-role="content" id="index-content">
<div id="menu">
Map
</div>
</div>
</div>
</body>
</html>
map.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.min.js"></script>
<title>MyTitle</title>
</head>
<body>
<div data-role="page" id="map-page">
<div data-role="content" id="content">
<div id="canvas-map" style="height:100%"/>
</div>
<style>
#content {
padding: 0 !important;
position : absolute !important;
top : 0 !important;
right : 0 !important;
bottom : 40px !important;
left : 0 !important;
}
</style>
<script type="text/javascript">
$(document).on('pageshow', '#map-page', function(e, data) {
var marker, map,
myLocation = {
lat: 50,
lon: -80
},
mapOptions = {
zoom: 5,
mapTypeId: google.maps.MapTypeId.PLAN,
center: new google.maps.LatLng(myLocation.lat, myLocation.lon)
};
$('#canvas-map').css("height", "200px").css("padding", "0px");
map = new google.maps.Map(document.getElementById('canvas-map'), mapOptions);
marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(myLocation.lat, myLocation.lon),
});
});
</script>
</div>
</body>
</html>
If you take a look at this ARTICLE you will find much more information regarding this topic plus examples.
Try to add following code...
$('#canvas-map').on('pageshow', function(){
google.maps.event.trigger(canvas-map, "resize");
});
this will fire resize event and reload the map on your page.
Just for completeness: The action of drawing the map should be performed after the page loads, that is when the page has actual values for width and height and you can initialize it as follows:
var map; //declared as global so you can access the map object and add markers dynamically
$("#canvas-map").on( "pageshow", function() {
var mapProp = {
center:new google.maps.LatLng(53.6721226, -10.547924),
zoom:13,
mapTypeId:google.maps.MapTypeId.ROADMAP
};
map=new google.maps.Map(document.getElementById("map-canvas"),mapProp);
});
No refresh needed
I am using Google Maps JavaScript API to load map inside my mobile website. When I navigate from the previous page map won't load but if I refresh the page map load as expected. If I use the JavaScript inside the body even the page is not loading. I can't figure out the problem. Is it something with the previous page code ?
Here is my code in Head tag.
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="css/jquery.mobile-1.1.0.min.css" />
<link href="css/site.css" rel="stylesheet" type="text/css" />
<script src="./js/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=xxxxxxxx&sensor=false">
</script>
<script type="text/javascript">
function initialize() {
var myLatlng = new google.maps.LatLng(<?php echo $longtitude ?>, <?php echo $latitude ?>);
var mapOptions = {
zoom: 10,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Location'
});
}
google.maps.event.addDomListener(window, 'load', initialize);
$(document).delegate('#content', 'pageinit', function () {
navigator.geolocation.getCurrentPosition(initialize);
});
</script>
</head>
Here is my Body Tag
<body >
<div id="wrapper">
<div class="header">
<img src="images/logo-small.png" alt="logo"/>
</div>
<div class="back">
<a data-rel="back"><img src="images/back.png"/></a>
</div>
<div id="content">
<div class="list">
<div class="list-items" id="info">
<?php echo "<h3>$sa1<span>$postcode<span>$sa2</span></span></h3><h2>$price</h2>";?>
<br class="clear" />
<br class="clear" />
</div>
</div>
<br class="clear" />
<div id="map-canvas">
</div>
</div>
</div>
</body>
I refer question This and This but it's not working with my code.
Problems
First of all, why are you using jQuery Mobile? I don't see the point in your current example.
In this case jQuery Mobile is the main problem. Because jQuery Mobile is used everything will be loaded into the DOM. When you "navigate from the previous page" page is not refreshed and this line:
google.maps.event.addDomListener(window, 'load', initialize);
can't trigger. It will trigger only if you manually refresh the page.
Second thing, you cant use jQuery Mobile page events without having any page what so ever. In your code you have this part:
$(document).delegate('#content', 'pageinit', function () {
navigator.geolocation.getCurrentPosition(initialize);
});
For it to initialize successfully div with an id content MUST have another attribute called data-role="page", like this:
<div id="content" data-role="page">
</div>
Third thing. Lets assume everything else is ok. Pageinit will not trigger from the HEAD. When jQuery Mobile loads pages it loads them into the DOM and only BODY part will be loaded. So for your map to work you need to move our javascript to the BODY (including a css). In you first example it didnt worked because you were triggering page even on a non-page div container.
And last thing, if you want to use jQuery Mobile properly you will need to take care correct version of jQuery is used with a correct version of jQuery Mobile. If you want to be safe use jQ 1.8.3 with jQM 1.2
Solution
Here's a working solution:
<!DOCTYPE html>
<html>
<head>
<title>jQM Complex Demo</title>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
<script src="http://www.dragan-gaic.info/js/jquery-1.8.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>
</head>
<body>
<style>
#map-canvas {
width: 300px;
height: 300px;
}
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
<script type="text/javascript">
function initialize() {
var myLatlng = new google.maps.LatLng(33.89342, -84.30715);
var mapOptions = {
zoom: 10,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Location'
});
}
//google.maps.event.addDomListener(window, 'load', initialize);
$(document).on('pageshow', '#wrapper', function(e, data){
initialize();
});
</script>
<div id="wrapper" data-role="page">
<div class="header">
<h3>Test</h3>
<img src="images/logo-small.png" alt="logo"/>
</div>
<div id="content">
<div id="map-canvas"></div>
</div>
</div>
</body>
</html>
Working examples and much more information regarding this topic can be found in this ARTICLE.
just add: data-ajax="false" to the link tag which redirects to the page that contains your map. for example, if map.aspx contains your map, you can link to it like this:
<a href="map.aspx" data-ajax="false">
I was having same problem but I have no any jquery-mobile libraray or any other which would conflict the map. Struggling a hard time, I found a solution for my project:
Doesn't work:
<script src="http://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY" async defer>
</script>
Works (Removing async and defer attributes):
<script src="http://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
Hope! This helps someone if the other solutions doesn't work. Try this only if none of other solution work because it is not good suggestion as we know google page speed guide or google map api guide says to use it.
I have also same problem with
google.maps.event.addDomListener(window, 'load', initialize); where initialize is my method .
I just add few line of code before google.maps.event.addDomListener(window, 'load', initialize);
Code is
$(document).ready( function () {
initialize();
});
and this code is working for me
You should use the pageloadevent to load everything. This way everything is loaded once jquery Mobile has done all the DOM changes it needs. I've had this same problem and that's what helped.
$(document).on('pageload', function() {
initialize();
});
It's in the docs: http://api.jquerymobile.com/pageload/
EDIT: Sometimes it also helps to load the markers in a separate function than the one loading the map.