Why does my html page with two 'Mobile' pages inside have to be refreshed or have the little edges moved to show my map in this? See my fiddle or the code below:
I have a mobile page document (html) that has two jQuery Mobile pages.
1. The landing page where you are asked to have your position known.
2. The OpenLayers3 map page which takes your position and centers the map on it when opened.
My trouble is: the map will build and it will center on the position but does not render until after I resize refresh the 'map' edges or the browser window. I suspect it has something to do with page events but am not sure.
Is there a property that I am missing?
Andy
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>MobilePg</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"/>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<link rel="stylesheet" href="http://openlayers.org/en/v3.0.0/css/ol.css"/>
<script type="text/javascript" src=" http://openlayers.org/en/v3.0.0/build/ol.js"></script>
<style>
#myFooterPosit {
color: gray;
}
</style>
<script>
var x, y;
$(document).ready(function () {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
});
function showPosition(position) {
var positThing = $('#myFooterPosit');
positThing.text('lat: ' + position.coords.latitude + " : " + " long: " + position.coords.longitude);
x = position.coords.latitude;
y = position.coords.longitude;
}
</script>
</head>
<body>
<script>
$(document).on("pagebeforeshow", "#mapPage", function () {
makeMap();
})
</script>
<!-- Landing page Point of Entry-->
<div data-role="page" id="homePage">
<div data-role="header">
Map
<h1>Mbl Map Input</h1>
Search
</div>
<div data-role="main" class="ui-content">
<p>My Content..</p>
</div>
<div data-role="footer">
<h1><span id="myFooterPosit"></span></h1>
</div>
</div>
<!-- Map Page -->
<script>
function makeMap() {
try {
alert(x + " : " + y);
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
title: 'OSM',
type: 'base',
visible: true,
source: new ol.source.OSM()
})],
view: new ol.View({
center: ol.proj.transform([y, x], 'EPSG:4326', 'EPSG:3857'),
zoom: 14
})
});
} catch (e) {
alert(e.message);
}
}
</script>
<div data-role="page" id="mapPage">
<div data-role="header">
Home
<h1>Map</h1>
</div>
<div data-role="main" class="ui-content">
<div id="map" class="map" style="height:200px;"></div>
</div>
<div data-role="footer">
<h1><span id="myFooterPosit"></h1>
</div>
</div>
</body>
</html
>
You can use the pagecontainer widget's show event:
http://api.jquerymobile.com/pagecontainer/#event-show
Updated FIDDLE
var x, y;
$(document).on("pagecreate","#homePage", function(){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
});
$(document).on( "pagecontainershow", function( event, ui ) {
if (ui.toPage.prop("id") == "mapPage"){
makeMap();
}
});
function showPosition(position) {
var positThing = $('#myFooterPosit');
positThing.text('lat: ' + position.coords.latitude + " : " + " long: " + position.coords.longitude);
x = position.coords.latitude;
y = position.coords.longitude;
}
function makeMap() {
try {
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
title: 'OSM',
type: 'base',
visible: true,
source: new ol.source.OSM()
})],
view: new ol.View({
center: ol.proj.transform([y, x], 'EPSG:4326', 'EPSG:3857'),
zoom: 14
})
});
} catch (e) {
alert(e.message);
}
}
Related
I am having an issue where I am trying to load a WMTS feed using Openlayers and seem not to be getting good results. For ArcGis services this seems to go through but not GeoServer's WMTS services. The code is as shown below. I keep getting a javascript error
TypeError: Argument 2 of CanvasRenderingContext2D.putImageData is not a finite floating-point value.
The code I am using is shown below. Regardless of changing the projection the error remains the same. Please advise. Raw Gist here
<!DOCTYPE html>
<html>
<head>
<title>WMTS example</title>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"> </script>
<link rel="stylesheet" href="http://openlayers.org/en/v3.8.2/css/ol.css" type="text/css">
<script src="http://openlayers.org/en/v3.8.2/build/ol.js"></script>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>
</div>
<script>
var projection = ol.proj.get('EPSG:4326');
var projectionExtent = projection.getExtent();
var size = ol.extent.getWidth(projectionExtent) / 256;
var resolutions = new Array(21);
var matrixIds = new Array(21);
for (var i=0; i<21; ++i) {
matrixIds[i] = "EPSG:4326:" + i;
}
var attribution = new ol.Attribution({
html: 'Tiles © <a href="http://services.arcgisonline.com/arcgis/rest/' +
'services/Demographics/USA_Population_Density/MapServer/">ArcGIS</a>'
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
opacity: 0.7
}),
new ol.layer.Tile({
opacity: 0.7,
source: new ol.source.WMTS({
attributions: [attribution],
url: 'http://suite.opengeo.org/geoserver/gwc/service/wmts',
layer: 'opengeo:countries',
matrixSet: 'ESPG:4326',
format: 'image/png',
style : 'default',
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: resolutions,
matrixIds: matrixIds
}),
wrapX: true
})
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
center: [-13677832, 5213272],
//center: [-11158582, 4813697],
zoom: 1
})
});
</script>
</body>
</html>
Your resolutions array is just filled with undefineds, right? You should fill it with you desired resolutions.
You should to init your resolution array like this:
for (var z = 0; z < 21; ++z) {
resolutions[z] = size / Math.pow(2, z);
matrixIds[z] = "EPSG:4326:" + z;;
}
Did you set map's projection to ol.proj.get('EPSG:4326')?
var view = new ol.View({
center: [0, 0],
zoom: 1,
projection: ol.proj.get('EPSG:4326')
});
I found several other people on here had the same issue with the Fusion Table Wizard generating HTML that works in the preview but when you try to embed the code on your own webpage pieces are missing. Mine for example, will show the search bar but not the map. Someone else had the same problem and it turned out that quotes were missing around the id number. But mine does have the appropriate quotes. So I'm wondering what is wrong with my code. I've compared my code to theirs several times looking for what is missing but can't figure it out.
Our webpage is hosted by jimdo, and I have to use the html/widget. I copy and paste the code into that. But it does say that some code requires you to edit the head section. That wouldn't be the problem would it? And if it is, what would I put in the head section and what would I put in the body section?
Here is my code:
<!DOCTYPE html>
<html>
<head>
<style>
#map-canvas { width:500px; height:400px; }
.layer-wizard-search-label { font-family: sans-serif };
</style>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<script type="text/javascript">
var map;
var layer_0;
var layer_1;
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(45.0817001045586, -89.74025),
zoom: 6
});
var style = [
{
featureType: 'all',
elementType: 'all',
stylers: [
{ saturation: 11 }
]
}
];
var styledMapType = new google.maps.StyledMapType(style, {
map: map,
name: 'Styled Map'
});
map.mapTypes.set('map-style', styledMapType);
map.setMapTypeId('map-style');
layer_0 = new google.maps.FusionTablesLayer({
query: {
select: "col18",
from: "1_rIjSmE6MLjWMF4JH-OIzHFcYCjKr-8eytn9v6Y"
},
map: map,
styleId: 2,
templateId: 3
});
layer_1 = new google.maps.FusionTablesLayer({
query: {
select: "col4",
from: "1ZLOwVcCWsIA-1WNg_yICWjaRdWOTeVy9xpudaQ"
},
map: map
});
}
function changeMap_0() {
var whereClause;
var searchString = document.getElementById('search-string_0').value.replace(/'/g, "\\'");
if (searchString != '--Select--') {
whereClause = "'Counties' CONTAINS IGNORING CASE '" + searchString + "'";
}
layer_0.setOptions({
query: {
select: "col18",
from: "1_rIjSmE6MLjWMF4JH-OIzHFcYCjKr-8eytn9v6Y",
where: whereClause
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
<div style="margin-top: 10px;">
<label class="layer-wizard-search-label">
Counties
<input type="text" id="search-string_0">
<input type="button" onclick="changeMap_0()" value="Search">
</label>
</div>
</body>
</html>
Can somebody help me, because I have been doing this for days now. And have finally decided to actually ask for help. Any input you have would be greatly appreciated!
Thanks, Angie
Paste this:
<div id="map-canvas" style="width:500px; height:400px;"></div>
<div style="margin-top: 10px;">
<label class="layer-wizard-search-label">
Counties
<input type="text" id="search-string_0">
<input type="button" onclick="changeMap_0()" value="Search">
</label>
</div>
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false">
</script>
<script type="text/javascript">
var map;
var layer_0;
var layer_1;
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(45.0817001045586, -89.74025),
zoom: 6
});
var style = [
{
featureType: 'all',
elementType: 'all',
stylers: [
{ saturation: 11 }
]
}
];
var styledMapType = new google.maps.StyledMapType(style, {
map: map,
name: 'Styled Map'
});
map.mapTypes.set('map-style', styledMapType);
map.setMapTypeId('map-style');
layer_0 = new google.maps.FusionTablesLayer({
query: {
select: "col18",
from: "1_rIjSmE6MLjWMF4JH-OIzHFcYCjKr-8eytn9v6Y"
},
map: map,
styleId: 2,
templateId: 3
});
layer_1 = new google.maps.FusionTablesLayer({
query: {
select: "col4",
from: "1ZLOwVcCWsIA-1WNg_yICWjaRdWOTeVy9xpudaQ"
},
map: map
});
}
function changeMap_0() {
var whereClause;
var searchString = document.getElementById('search-string_0').value.replace(/'/g, "\\'");
if (searchString != '--Select--') {
whereClause = "'Counties' CONTAINS IGNORING CASE '" + searchString + "'";
}
layer_0.setOptions({
query: {
select: "col18",
from: "1_rIjSmE6MLjWMF4JH-OIzHFcYCjKr-8eytn9v6Y",
where: whereClause
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
As it seems everything except the contents of <body> will be removed when you paste a complete HTML-source.
I've been working on this for a couple so getting to this point should make me very happy. However, I cannot figure out my infowindow output is adding "\n" to every new line. No idea how it's getting there. The geolocation is also being appended to the search result infowindow. I'd like to remove that as well.
Here is a link to the map: http://58design.com/gmaps/
Here is my code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Sheriff | Zone Leader Look Up</title>
<meta name="author" content="Santa Clarita Valley Sheriff" />
<meta name="copyright" content="Copyright 2013 SCV Sheriff" />
<meta name="keywords" content="Santa Clarita Valley Sheriff, SCV Sheriff, Canyon Country, Valencia, Saugus, Newhall, Castaic, Gorman, Stevenson Ranch, " />
<meta name="description" content="Santa Clarita Valley Sheriff Zone Leader Contact Inforamtion Look Up." />
<meta name="robots" content="index,follow" />
<meta name="Googlebot" content="follow" />
<meta name="googlebot" content="archive" />
<meta name="distribution" content="global" />
<!--Load the AJAX API-->
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
//<![CDATA[
google.load('visualization', '1', {'packages':['corechart', 'table', 'geomap']});
//var FusionTableID = 1931355;
var FusionTableID = '1uSGM1yPMJBlu74Znm4fPqdCsJjteB_kQ_nGz3tk';
var map = null;
var geocoder = null;
var infowindow = null;
var marker = null;
function initialize() {
geocoder = new google.maps.Geocoder();
infowindow = new google.maps.InfoWindow({size: new google.maps.Size(150,50) });
// create the map
var myOptions = {
zoom: 10,
center: new google.maps.LatLng(34.452789398370045, -118.51948001245114),
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
//layer = new google.maps.FusionTablesLayer(FusionTableID,{suppressInfoWindows:true});
layer = new google.maps.FusionTablesLayer({
map: map,
suppressInfoWindows: true,
heatmap: { enabled: false },
query: {
select: "col2",
from: "1uSGM1yPMJBlu74Znm4fPqdCsJjteB_kQ_nGz3tk",
where: "",
},
options: {
styleId: 2,
templateId: 2
}
});
layer.setMap(map);
google.maps.event.addListener(layer, "click", function(e) {
var content = e.row['description'].value+"<br><br>";
infowindow.setContent(content);
infowindow.setPosition(e.latLng);
infowindow.open(map);
});
}
function showAddress(address) {
var contentString = address+"<br>Outside Area";
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var point = results[0].geometry.location;
contentString += "<br>"+point;
map.setCenter(point);
if (marker && marker.setMap) marker.setMap(null);
marker = new google.maps.Marker({
map: map,
position: point
});
// query FT for data
var queryText ="SELECT 'description', 'Zone Area' FROM "+FusionTableID+" WHERE ST_INTERSECTS(\'Zone Area\', CIRCLE(LATLNG(" + point.toUrlValue(6) + "),0.5));";
// document.getElementById('FTQuery').innerHTML = queryText;
queryText = encodeURIComponent(queryText);
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
//set the callback function
query.send(openInfoWindowOnMarker);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function openInfoWindowOnMarker(response) {
if (!response) {
alert('no response');
return;
}
if (response.isError()) {
alert('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
return;
}
FTresponse = response;
//for more information on the response object, see the documentation
//http://code.google.com/apis/visualization/documentation/reference.html#QueryResponse
numRows = response.getDataTable().getNumberOfRows();
numCols = response.getDataTable().getNumberOfColumns();
var content = "<b>Outside area</b><br><br>";
var unionBounds = null;
// alert(numRows);
for (var i=0; i < numRows; i++) {
var name = FTresponse.getDataTable().getValue(i,0);
var kml = FTresponse.getDataTable().getValue(i,1);
content = response.getDataTable().getValue(i,0)+"<br><br>";
}
infowindow.setContent(content+marker.getPosition().toUrlValue(6));
// zoom to the bounds
// map.fitBounds(unionBounds);
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
google.maps.event.trigger(marker, 'click');
}
</script>
</head>
<body onload="initialize()">
<div id="content">
<h1>SCV Sheriff Reporting Zones</h1>
<p>Use the map below to determine your area's Zone Leader. Enter your street address, city and zip code in the search field below to view the Zone Leader's contact info.</p>
<form action="#" onsubmit="showAddress(this.address.value); return false" style="padding:10px 0px 30px 0px; background:none;">
<label>Address Search</label>
<input type="text" size="60" name="address" value="23920 Valencia Blvd. Santa Clarita, CA 91355" class="address" />
<input type="submit" value="Search" />
</p>
<div id="map_canvas" style="width: 516px; height: 387px; margin-bottom:30px; border:1px solid #999;"></div>
</form>
</div>
<div id="sidebar">
</div>
<div class="clear"><!--clear--></div>
</div>
</body>
</html>
The problem is in the data in your FusionTable (the line feeds are getting translated into "\n"). I fixed the entry for "Gorman" in my example (by removing the extraneous line feeds).
This line of my code is appending the geolocation to the search result infowindow:
infowindow.setContent(content+marker.getPosition().toUrlValue(6));
I have set up a project that uses require.js, backbone.js, openlayers (mobile single file build) and jquery mobile.
Now I have some issues displaying the map correctly, because no tiles are loading. I have figured out how to load the openlayers api with the require.js shim parameter:
shim: {
"backbone": {
"deps": [ "underscore", "jquery" ],
"exports": "Backbone"
},
"openlayers": {
"exports": "OpenLayers"
}
}
In the MapView.js file I create a new openlayers map:
define([ "jquery", "backbone", "openlayers" ], function( $, Backbone, OpenLayers ) {
var MapView = Backbone.View.extend( {
// The View Constructor
initialize: function() {
console.log(3);
var mapOptions = {
div: this.el,
maxExtent: new OpenLayers.Bounds(-174,18.4,-63.5,71),
maxResolution: 0.25,
projection: "EPSG:102100",
theme: "/css/theme/default/style.css",
layers: [
new OpenLayers.Layer.OSM("OpenStreetMap", null, {
transitionEffect: 'resize'
})
]};
this.map = new OpenLayers.Map( mapOptions );
},
render: function() {
console.log(4);
}
} );
return MapView;
} );
Now the map works partly. I can see the Zoom Buttons which are added by openlayers at the top-left of the map, but no Tiles are loaded. Firebug told me, that there isn't even a request for the tiles.
At the moment I have no clue whats the problem might be.
For completetion this is my backbone router:
define([ "jquery", "backbone", "../models/Map", "../views/Map" ], function( $, Backbone, MapModel, MapView ) {
var Router = Backbone.Router.extend( {
initialize: function() {
console.log(2);
this.mapView = new MapView( { el: "#mapView" } );
Backbone.history.start();
},
// Backbone.js Routes
routes: {
"": "home",
},
// Home method
home: function() {
console.log(0);
$.mobile.changePage( "#map" , { reverse: false, changeHash: false } );
},
});
return Router;
} );
and the Page html
<!doctype html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="/css/jquerymobile.css" />
<script src="/js/libs/require-min.js" data-main="/js/mobile"></script>
<style>
#mapView {
height: 500px;
width: 500px;
}
</style>
</head>
<body>
<div id="map" data-role="page" data-title="Map">
<div data-role="header">
<h1>Map</h1>
</div><!-- /header -->
<div data-role="content">
<div id="mapView"></div>
</div><!-- /content -->
</div>
</body>
</html>
Any ideas?
I figured it out now. All I had to do is add this.map.zoomToMaxExtent();. For some reason without that the map was not able to calculate the correct visible extent for the tiles.
I can't seem to make the "reverse" slide effect while handling the "swiperight" event. So, the code below works fine but I would like when I make the "swiperight" that the next page would slide in from the left side and not right hand side. I did search the documentation and added the reverse: true as as it recomends in to the "swiperight":
$.mobile.changePage("#page"+nextPage, {transition : "slide", reverse:true});
but this does not provide the wanted effect. Can you point out where am I doing it wrong?
I have the following code on jsFiddle:
html:
<!DOCTYPE html>
<html>
<head>
<title>jQuery Mobile Application</title>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />
<script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>
</head>
<body>
<section id="page1" data-role="page">
<header data-role="header"><h1>jQuery Mobile</h1></header>
<div data-role="content" class="content">
<p>First page!</p>
</div>
<footer data-role="footer"><h1>O'Reilly</h1></footer>
</section>
<section id="page2" data-role="page">
<header data-role="header"><h1>jQuery Mobile</h1></header>
<div data-role="content" class="content">
<p>Second page!</p>
</div>
<footer data-role="footer"r><h1>O'Reilly</h1></footer>
</section>
<section id="page3" data-role="page">
<header data-role="header"><h1>jQuery Mobile</h1></header>
<div data-role="content" class="content">
<p>Third page!</p>
</div>
<footer data-role="footer"><h1>O'Reilly</h1></footer>
</section>
</body>
</html>
jQuery:
(function($) {
var methods = {
init : function(options) {
var settings = {
callback: function() {}
};
if ( options ) {
$.extend( settings, options );
}
$(":jqmData(role='page')").each(function() {
$(this).bind("swiperight", function() {
var nextPage = parseInt($(this).attr("id").split("page")[1]) - 1;
if (nextPage === 0)
nextPage = 3;
$.mobile.changePage("#page"+nextPage, "slide");
});
$(this).bind("swipeleft", function() {
var nextPage = parseInt($(this).attr("id").split("page")[1]) +1;
if (nextPage === 4)
nextPage = 1;
$.mobile.changePage("#page"+nextPage, "slide");
});
})
}
}
$.fn.initApp = function(method) {
if ( methods[method] ) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
else if ( typeof method === 'object' || ! method ) {
return methods.init.apply( this, arguments );
}
else {
$.error( 'Method ' + method + ' does not exist' );
}
}
})(jQuery);
$(document).ready(function(){
$().initApp();
});
OK first off you're using a Alpha version of jQM and the docs you are referring to a for jQM 1.1.1. I've updated your jsfiddle to use the latest jQM 1.2
http://jsfiddle.net/GYAB7/2/
And I've added the correct syntax for the reverse swipe transition
$.mobile.changePage("#page"+nextPage, {
transition: "slide",
reverse: false
});
});
and the reverse transition
$.mobile.changePage("#page"+nextPage, {
transition: "slide",
reverse: true
});
});