I have a concern about the google maps plugin used with Onsen UI:
Google Maps Plugin
When my google maps div (canvas) is located directly in the index.html page, I can show the google map perfectly.
When I travel to any other page through the Onsen UI side menu, google map cannot display anymore on any of the pages travelled to. And when I travel back to the index.html page, it does not work anymore (maps appear in white).
If I put in the navigator definition any start page attribute, it does not work neither ( ons-navigator id="navi" page="start_page" /ons-navigator) That is why I only let : ons-navigator id="navi" /ons-navigator
I know there is a similar topic about that problem but it has been closed and problem was not fixed : github.com/mapsplugin/cordova-plugin-googlemaps/issues/324
I attach a pdf file to describe the sequence and the problem (you can see it online without downloading):
PDF_problem_description
Thank you very much for your help
Here is my Index.html :
<!DOCTYPE html>
<html lang='en' ng-app='app'>
<head>
<!-- meta Charset-->
<meta charset='utf-8'>
<script src='js/angular.min.js'></script>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<link rel='stylesheet' href='onsenui/css/onsenui.css'/>
<link rel='stylesheet' href="css/onsen-css-components.css"/>
<script src='onsenui/js/onsenui.js'></script>
<script src='onsenui/js/angular-onsenui.js'></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<meta name='viewport' content='user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width'>
</head>
<body ng-controller="AppCtrl">
<ons-splitter>
<ons-splitter-side id="menu" side="left" width="220px" collapse swipeable >
<ons-page>
<ons-list>
<ons-list-item>
<div class="text_menu_color" ng-click="fn.load('index.html')">Index</div>
</ons-list-item>
<ons-list-item>
<div class="text_menu_color" ng-click="fn.load('html/dashboard.html')">Dashboard</div>
</ons-list-item>
</ons-list>
</ons-page>
</ons-splitter-side>
<ons-splitter-content>
<ons-navigator id="navi"></ons-navigator>
</ons-splitter-content>
</ons-splitter>
<h3>Index.html</h3>
<div id="map_canvas_1" style="position:fixed;width:160px;height:320px;left:10px;bottom:150px;background: blue;border: 2px solid black"><h3>map 1</h3></div>
<button ng-click="show_map_1()" style="position:fixed;width:160px;height:100px; left:10px;bottom:30px">Show map 1</button>
<script>
ons.platform.select('android')
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {window.powermanagement.acquire()}
angular.module('app', ['onsen'])
.controller('AppCtrl', function($scope) {
$scope.show_map_1 = function(){
$scope.map_1=""
$scope.map_1 = plugin.google.maps.Map.getMap(document.getElementById('map_canvas_1'));
$scope.map_1.addEventListener(plugin.google.maps.event.MAP_READY, $scope.onMapReady_1)
}
$scope.show_map_2 = function(){
$scope.map_2=""
$scope.map_2 = plugin.google.maps.Map.getMap(document.getElementById('map_canvas_1'));
$scope.map_2.addEventListener(plugin.google.maps.event.MAP_READY, $scope.onMapReady_2)
}
$scope.onMapReady_1 = function() {
$scope.map_1.setDiv(document.getElementById('map_canvas_1'))
$scope.map_1.refreshLayout();
$scope.map_1.setBackgroundColor('green')
}
$scope.onMapReady_2 = function() {
$scope.map_2.setDiv(document.getElementById('map_canvas_2'))
$scope.map_2.refreshLayout();
$scope.map_2.setBackgroundColor('green')
}
$scope.fn = {};
$scope.fn.load = function(page) {
var menu = document.getElementById('menu');
var navi = document.getElementById('navi');
menu.close();
navi.resetToPage(page, {animation: 'slide', animationOptions:{duration: 0.4, delay: 0, timing: 'ease-in'}});
};
})
</script>
</body>
</html>
Here is my Dashboard.html :
<ons-page>
<h3>Dashboard.html</h3>
<div id="map_canvas_2" style="position:fixed;width:160px;height:320px;right:10px;bottom:150px;background: blue;border: 2px solid black" ><h3>map 2</h3></div>
<button ng-click="show_map_2()" style="position:fixed;width:160px;height:100px; right:10px;bottom:30px" >Show map 2</button>
</ons-page>
OnsenUI adds dynamically a background div for pages, inspect you map container element and check as all parents must be transparent with this css style background-color: rgba(0,0,0,0);
For me, there's div hiding the map with class "page--background" which is not dynamically set to transparent by the plugin (because it's a no parent div with absolute position), sample :
<div class="page__background page--material__background" __plugindomid="pgm423934967639"></div>
<div class="page__content page--material__content _gmaps_cdv_" __plugindomid="pgm1136479823937">
<div id="mymap-container" class="gmap-container _gmaps_cdv_" __pluginmapid="map_0_147744461355" style="background-color: rgba(200, 200, 200, 0.5); position: relative; overflow: hidden;" __plugindomid="pgm888819903812"><div __plugindomid="pgm1177970622685" style="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; overflow: visible; z-index: 0;"></div></div></div>
I apply the transparent background style with jQuery once the map is initialized to reveal it:
mapDiv = document.getElementById("mymap-container");
myMap = plugin.google.maps.Map.getMap(mapDiv);
myMap.one(plugin.google.maps.event.MAP_READY, myMapInit);
myMapInit = function () {
console.log("Map init done!"); // DEBUG
$(".page__background").css( "background-color", "rgba(0,0,0,0)" );
}
This is explained here (bottom of page): https://github.com/mapsplugin/cordova-plugin-googlemaps-doc/blob/master/v1.4.0/TroubleShooting/Blank-Map/README.md
I managed to solve the problem.
For those who get the same trouble using the google maps plugin with Onsen UI, use google maps without the plugin, and it will work perfectly, no matter the page you travel to, through the onsen navigator.
Somebody already posted an explanation on how to use google maps without the plugin. It works very well:
Using google maps without plugin
Cheers
Related
dialog is open by module on page.
html code:
<!DOCTYPE html>
<!--
#license
Copyright 2019 Google LLC. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
-->
<html>
<head>
<title>Simple Map</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<dialog id="dialog">
<form method="dialog">
<input type="text" id="google">
</form>
</dialog>
<!--
The `defer` attribute causes the callback to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises
with https://www.npmjs.com/package/#googlemaps/js-api-loader.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=places"
defer
></script>
</body>
</html>
and in js file, I created the google autocomplete and focus on the input field in the dialog.
js code:
let autocomplete;
const addressDialog = document.querySelector("#dialog");
const addressGoogleField = document.querySelector("#google");
addressDialog.showModal();
function fillInAddress() {
const place = autocomplete.getPlace();
console.log(place);
}
function initMap() {
autocomplete = new google.maps.places.Autocomplete(addressGoogleField, {
fields:["geometry"],
types:["geocode"]
});
addressGoogleField.focus();
autocomplete.addListener("place_changed", fillInAddress);
}
window.initMap = initMap;
results:
Google Places Autocomplete Box is behind the modal dialog.
I want to put autocomplete box in front of the dialog. What should I do?
This may be a z-index issue. The Google Place Autocomplete box ("pac-container" css class) is appended at the end of the body element, and not within your modal dialog.
To ensure the autocomplete box is above your modal dialog div. You can try and update your css with :
.pac-container {
z-index: 10000;
}
The 10000 z-index is just a value high enough to be above the modal z-index.
i have published suitability map on arc server. but my map does not display, i have followed arcgis java script api example. i want to display suitability map of the desired area. when user click on the map pop window display the analysis result here is my code
<!DOCTYPE html>
<html>
<head>
<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>Create web map from id</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
<link rel="stylesheet" href="css/layout.css">
<script src="https://js.arcgis.com/3.20/"></script>
<script>
require([
"dojo/parser",
"dojo/ready",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dojo/dom",
"esri/map",
"esri/urlUtils",
"esri/arcgis/utils",
"esri/dijit/Legend",
"esri/dijit/Scalebar",
"dojo/domReady!"
], function(
parser,
ready,
BorderContainer,
ContentPane,
dom,
Map,
urlUtils,
arcgisUtils,
Legend,
Scalebar
) {
ready(function(){
parser.parse();
//if accessing webmap from a portal outside of ArcGIS Online, uncomment and replace path with portal URL
arcgisUtils.arcgisUrl = "http://localhost:6080/arcgis/rest/services/Soil_Maps/changa_manga_soil_map/MapServer/0";
arcgisUtils.createMap("map").then(
function(response){
//update the app
dom.byId("title").innerHTML = response.itemInfo.item.title;
dom.byId("subtitle").innerHTML = response.itemInfo.item.snippet;
var map = response.map;
//add the scalebar
var scalebar = new Scalebar({
map: map,
scalebarUnit: "english"
});
//add the legend. Note that we use the utility method getLegendLayers to get
//the layers to display in the legend from the createMap response.
var legendLayers = arcgisUtils.getLegendLayers(response);
var legendDijit = new Legend({
map: map,
layerInfos: legendLayers
},"legend");
legendDijit.startup();
});
});
});
</script>
</head>
<body class="claro">
<div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline'" style="width:100%; height:100%;">
<div id="header" class="shadow roundedCorners" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
<div id="title"></div>
<div id="subtitle"></div>
</div>
<div id="map" class="roundedCorners shadow" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
<div id="rightPane" class="roundedCorners shadow" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'" >
<div id="legend"></div>
</div>
</div>
</body>
</html>
well, as i can see the question and code you added above below are this things you want to achieve (correct me if i am wrong)-
create a map
add a published layer(arcgis layer url) on the map
show popup on the click of published gis layer.
As your example says you don't have a webmap id so you not need to worry about that.
Below is the working example for that-
require([
"dojo/dom",
"dojo/dom-construct",
"esri/map",
"esri/dijit/InfoWindow",
"esri/layers/FeatureLayer",
"esri/InfoTemplate",
"dojo/string",
"dojo/domReady!"
], function(
dom,
domConstruct,
Map,
InfoWindow,
FeatureLayer,
InfoTemplate,
string
) {
var infoWindow = new InfoWindow({}, domConstruct.create("div"));
infoWindow.startup();
// **** update center according to your feature layer url
var map = new Map("mapDiv", {
center: [-122.41, 37.78],
zoom: 17,
basemap: "topo",
infoWindow: infoWindow
});
var template = new InfoTemplate();
//*** update the title field name according to your feature layer url
template.setTitle("<b>${qAddress}</b>");
template.setContent("${*}");
// ****** replace with your Feature layer url "http://localhost:6080/arcgis/rest/services/Soil_Maps/changa_manga_soil_map/MapServer/0"
var featureLayer = new FeatureLayer("https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Street_Trees/FeatureServer/0",{
infoTemplate: template,
outFields: ["*"]
});
map.addLayer(featureLayer);
map.infoWindow.resize(180, 175);
});
html, body {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color:#fff;
overflow:hidden;
}
#header{
border:solid 2px #AAc4c4;
background:#fff;
color:#749749;
border-radius: 4px;
font-size:14px;
padding-left:20px;
font-weight:700;
}
#map{
padding:1px;
border:solid 2px #AAc4c4;
border-radius: 4px;
}
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css">
<script>var dojoConfig = {
parseOnLoad: true
};
</script>
<script src="https://js.arcgis.com/3.20/"></script>
<body>
<div id="mapDiv"></div>
</body>
Note- Update the sample code as per comments in it.
If you want more info let me know i will update the answer accordingly.
Hoping this will help you :)
Well, you apparently adapted this sample:
https://developers.arcgis.com/javascript/3/jssamples/ags_createwebmapid.html
I am not sure if this is what you want, as using webmaps needs some licensing, I guess. In any case, you need to change few lines in your example. Instead of
<link rel="stylesheet" href="css/layout.css">
you should have
<link rel="stylesheet" href="https://developers.arcgis.com/javascript/3/samples/ags_createwebmapid/css/layout.css">
to load the original CSS file. You should make your own copy and load it from your server.
More important is to change this line:
arcgisUtils.arcgisUrl = "http://localhost:6080/arcgis/rest/services/Soil_Maps/changa_manga_soil_map/MapServer/0";
which should be:
arcgisUtils.arcgisUrl = "https://www.arcgis.com/sharing/rest/content/items/";
or, as the sample suggests, path with YOUR portal URL.
And, last but not least, the next line must be something like:
arcgisUtils.createMap("ef9c7fbda731474d98647bebb4b33c20","map").then(
I am trying to change the width and height of the map. I want to show the map on full width of the page. Map is visible on half of the page without any styles. but when i try to implement styles to change height the map disappears from the page.
here is the full code of my html with the styles in the head tag and map div is at the bottom.
<html ng-app="myApp">
<head>
<!-- Style Sheets includes -->
<link rel="stylesheet" href="css/bootstrap.min.css">
<link href="css/customstyle.css" rel="stylesheet" type="text/css">
<!-- Script includes -->
<script data-require="angular.js#*" data-semver="1.3.14" src="js/angular.js"></script>
<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/ui-bootstrap-tpls-0.12.0.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="data.js"></script>
<script src="app.js"></script>
<script src="initmap.js"></script>
<style>
html, body, #map {
width: 25%;
height: 25%;
margin: 0;
padding: 0;
}
#map {
position: relative;
}
</style>
</head>
<body ng-controller="ApplicationController as appctrl">
<div class="container">
<div id="map"></div>
</div>
Here is the function for Initialize map
//Initializes the map.
function initialize() {
// Initial options. Centers on Sierra Leone.
var mapOptions = {
center: { lat: 8.4494988, lng: -11.7868289},
zoom: 8
};
// Creates the map.
map = new google.maps.Map(document.getElementById("map"),
mapOptions);
}
Then you change the size of the map div you need to resize the map (resize event of google maps) for a correct view of the content
In your case after change dinamically the size of div you can easily (re) invoke your initialize function...
(better if you before set map to null)
You can embed a basic map, a Street View image, driving directions, or a search into your website or blog from Google Maps.
When your viewers are signed in to Google, they can also see their home and work, saved places, and more in your map.
Get the code
Open Google Maps
Make sure the map or Street View image you'd like to embed shows up on the map.
In the top left corner, click the main menu .
Click Share or embed map.
At the top of the box that appears, choose the Embed map tab.
Choose the size you want, then copy the code and paste it into the source code of your website or blog.
Note: If you're using Maps in Lite mode, you won't be able to embed a map.
I'm trying to get google maps to display on a jquery mobile page.
The map works fine if I type I go directly to the page in the browser. However, when I click a link on another jqm page that goes to the map page, I just get a blank grey screen. The markers are actually there but they are plotted off the viewable area above and to the left of the viewport. Also weird is that I am able to drag on the canvas and bring the markers into view in a small, invisible viewport in the upper left hand corner (probably about 100 px wide and 200 px high), but I can't see the actual map.
Here's a screenshot: https://www.dropbox.com/s/p8berda8dbf6kh4/Screenshot%202015-05-25%2014.24.15.png?dl=0
If I immediately refresh the page after the failed load, everything shows up fine. So I don't think this is an API issue.
And one other oddity. If I wait like 10 min, the map will load properly when I click on the link to view the map. But then the next time I try it fails to load. I have to wait several minutes.
My code is basically ripped right from the jquery mobile site. Here's the relevant code:
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="http://maps.google.com/maps/api/js?sensor=false&key=MY_KEY"></script>
<!-- JQM and other scripts loaded here -->
<script>
$( document ).on( "pagecreate", "#map", function() {
var defaultLatLng = new google.maps.LatLng(34.0983425, -118.3267434);
drawMap(defaultLatLng);
function drawMap(latlng) {
var myOptions = {
zoom: 14,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
new google.maps.Marker({
position: latlng,
map: map,
title: "lat",
});
new google.maps.Marker({
position: new google.maps.LatLng(43.150358,-74.768798),
map: map,
title: 'hello',
});
}
});
</script>
<style>
#map, #map-canvas { width: 100%; height: 100%; padding: 0; }
</style>
</head>
<body>
#calling page
<div data-role="page" data-dom-cache="true" id="doors" data-url="doors" tabindex="0" class="ui-page ui-page-theme-a ui-page-active" style="position: relative; min-height: 559px;">
<div role="main" class="ui-content" id="">
View map
</div>
</div>
#map page
<div data-role="page" id="map" data-url="map" style="position: relative;">
<div data-role="header" data-theme="a"><h1>Maps</h1></div><div role="main" class="ui-content" id="map-canvas">
</div>
</div>
</body>
</html>
Well, after hours of banging my head against a wall I finally got it working by changing from pagecreate to pageshow. Interestingly pageshow is deprecated in v. 1.4.5 and is supposed to be replaced by pagecontainershow but pagecontainershow does not work.
And as usual, I find the answer within minutes of posting the question.
I was working on a solution based on
http://www.giscloud.com/sandbox/jsapi/html5/?mid=11695
On line 15, you can see the import (multi-line for easy reading)
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false">
</script>
Which in the last week started loading v3.10 (release) instead of v3.9 (now frozen).
The problem as you can see from the page is that the canvases are now loaded in the "MapPane" layer well below the other 6 layers (Ref: MapPanes). That layer is not interactive.
Has anyone come across such an issue, or better yet, is using the very solution in the link - and has upgraded it for v3.10?
JS Fiddle
doesn't work (v3.10)
works (v3.9)
More info
In v3.9, the map panes are laid out as
<div .. (parent)
<div .. z-index:100.. > --- << changed to 150
<div .. z-index:101.. >
<div .. z-index:102.. >
<div .. z-index:103.. >
<div .. z-index:104.. >
<div .. z-index:105.. >
<div .. z-index:106.. >
The code in the solution manipulates the z-index of the first pane ("MapPane"), which goes against the API's intentions...
el.map.getDiv().firstChild.firstChild.firstChild.firstChild.style.zIndex=150
My custom solution sets it to 104 instead, as I make use of the overlayMouseTarget (105) and floatPane (106) layers which need to go above it.
In v3.10, they have been rearranged as follows (you can make out the z-indexes 100-106):
<div .. (parent)
<div .. z-index:200.. >
<div .. z-index:101.. >
<div .. z-index:201.. >
<div .. z-index:102.. >
<div .. z-index:103.. >
<div .. z-index:202.. >
<div .. z-index:104.. >
<div .. z-index:105.. >
<div .. z-index:106.. >
<div .. z-index:100.. >
< overlay tile divs > --<< the divs parenting the canvases in the solution
<canvas ... >
I am thinking that the proper "fix" is to get the tiles moved to the floatShadow MapPane, but does it provide the tiling benefits that an OverlayMapType does, which seems to underpin the solution?
Direct access to pane is not better way.
To get panes correctly, your code should like this:
var dummyLayer = new google.maps.OverlayView();
dummyLayer.onAdd = function() {
var panes = this.getPanes();
console.log(panes.mapPane);
panes.mapPane.style.zIndex = 500;
};
dummyLayer.onRemove = function() {};
dummyLayer.draw = function() {};
dummyLayer.setMap(map);
Ok, I post whole code of yours.
<!doctype html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<title>GIS Cloud HTML5 Canvas Example</title>
<style>
body, html {
padding: 0;
margin: 0;
overflow: hidden;
}
</style>
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/standard.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://api.giscloud.com/sandbox/html5c.js"></script>
<script type="text/javascript">
var map;
function initialize() {
map = new google.maps.Map(document.getElementById("map_canvas"));
map.setZoom(4);
map.setMapTypeId('terrain');
map.setCenter(new google.maps.LatLng(35.818521016151, -100.932382588817));
var dummyLayer = new google.maps.OverlayView();
dummyLayer.onAdd = function() {
var panes = this.getPanes();
console.log(panes.mapPane);
panes.mapPane.style.zIndex = 500;
};
dummyLayer.onRemove = function() {
};
dummyLayer.draw = function() {
};
dummyLayer.setMap(map);
var gcmap = new giscloud.Html5Map(11695, map);
map.overlayMapTypes.insertAt(0, gcmap);
map.overlayMapTypes.insertAt(0, 0);
}
</script>
</head>
<body onload="initialize()">
<div style="text-align:center"><h2>GIS Cloud HTML5 Canvas Example</h2><p>Showing interactive HTML5 vector map overlay hosted on GIS Cloud. The original project is here. </p></div> <div id="map_canvas" style="width: 70%; height: 75%;margin:auto"></div>
<br />
<center>requires HTML5 compatible browser - article & benchmark: rasters vs vectors</center>
</body>
</html>