change width of InfoWindow in google maps php api - javascript

i'm using Google Maps PHP API, i'm need to change the width of the "infoWindow" that popup then i click on Markers, i tried a few ways do to that but i'm failed.
i'm using some api that i download from the internet, i'm using the function $MAP_OBJECT->addMarkerByCoords().
function getCreateMarkerJS() {
$_output = "
function createMarker(map, point, title, html, icon, icon_shadow, sidebar_id, openers){
var marker_options = {
position: point,
map: map,
title: title};
if(icon!=''){marker_options.icon = icon;}
if(icon_shadow!=''){marker_options.shadow = icon_shadow;}
//create marker
var new_marker = new google.maps.Marker(marker_options);
if(html!=''){
".(($this->info_window)?"
google.maps.event.addListener(new_marker, '".$this->window_trigger."', function() {
infowindow.close();
infowindow.setContent(html);
infowindow.open(map,new_marker);
});
if(openers != ''&&!isEmpty(openers)){
for(var i in openers){
var opener = document.getElementById(openers[i]);
opener.on".$this->window_trigger." = function() {
infowindow.close();
infowindow.setContent(html);
infowindow.open(map,new_marker);
return false;
};
}
}
":"")."
if(sidebar_id != ''){
var sidebar = document.getElementById(sidebar_id);
if(sidebar!=null && sidebar!=undefined && title!=null && title!=''){
var newlink = document.createElement('a');
".(($this->info_window)?"
newlink.onclick=function(){infowindow.open(map,new_marker); return false};
":"
newlink.onclick=function(){map.setCenter(point); return false};
")."
newlink.innerHTML = title;
sidebar.appendChild(newlink);
}
}
}
return new_marker;
}
";
return $_output;
}

The InfoWindow object has a method setOptions({opts}) which allows you to change the InfoWindowOptions. You can use this to set the maxWidth of the InfoWindow.
The actual width of the InfoWinodow is determined by the width of the content, changing the content's width will alter than InfoWindow.

Related

OL3: GetFeature from Layers by Coordinate

I want to get the Feature of a Layer by coordinate.
Furthermore I want to open this feature in a popup, which I have solved so far by an onclick event. But I want to realize by giving the coordinates of a feature and opening the popup of the featue.
I have a layer with the map and a layer with the features:
if (trackMap != null) {
for (var i = 0; i < trackMap.length; i++) {
var trackInfo = trackMap[i];
lat = parseFloat(trackInfo.lat);
lon = parseFloat(trackInfo.lon);
var layergpx = new ol.layer.Vector({
source: new ol.source.Vector({
parser: new ol.parser.GPX(),
url: '${contextRoot}/gps/gpx2' + trackInfo.url
})
});
layers.push(layergpx);
}
}
I want to get the feature of this layer in another Javascript function.
How I open a pop up by clicking on the map:
/**
* The Click Event to show the data
*/
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element,
positioning: ol.OverlayPositioning.BOTTOM_CENTER,
stopEvent: false
});
map.addOverlay(popup);
map.on('singleclick', function(evt) {
map.getFeatures({
pixel: evt.getPixel(),
layers: vectorLayers,
success: function(layerFeatures) {
var feature = layerFeatures[0][0];
if (feature) {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
popup.setPosition(coord);
$(element).popover({
'placement': 'top',
'html': true,
'content': feature.get('desc')
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
}
});
});
But I want this feature not to be opened by clicking on it on the map, but by entering a coordinate in a textfield and the map opens this pop up, like in the onclick event.
Take a look at this example to see if it helps you:
http://openlayers.org/en/latest/examples/kml.html
var displayFeatureInfo = function(pixel) {
map.getFeatures({
pixel: pixel,
layers: [vector],
success: function(featuresByLayer) {
var features = featuresByLayer[0];
var info = [];
for (var i = 0, ii = features.length; i < ii; ++i) {
info.push(features[i].get('name'));
}
document.getElementById('info').innerHTML = info.join(', ') || '&nbsp';
}
});
map.getFeatures() has this success callback where it delivers the features of the layers specified in layers: [vector]. Customize it at will to get what you need.
=== Update ===
In the OpenLayers 3's Map object you have a function: getPixelFromCoordinate
/**
* #param {ol.Coordinate} coordinate Coordinate.
* #return {ol.Pixel} Pixel.
*/
ol.Map.prototype.getPixelFromCoordinate = function(coordinate) {
var frameState = this.frameState_;
if (goog.isNull(frameState)) {
return null;
} else {
var vec2 = coordinate.slice(0, 2);
return ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix, vec2, vec2);
}
};

Display loading message on google maps

I'm trying to show a (loading....) message while my google map is loading. I have very little experience with maps and Java Script so, please excuse my code. The map was working, before I tried to add a sniplet of code to show a loading message. Now the map doesn't work at all, but I sure it's just an issue of putting the code in the wrong spot. (lack of skills) Can someone please show me what I doing wrong here.
<script type="text/javascript" src="./js/NauticalChartsAPI.js"></script>
<script type="text/javascript" src="./js/gmapsv3ext.js"></script>
<script language="JavaScript" type="text/javascript" src="./js/jquery-1.2.6.js"></script>
<script type="text/javascript">
if (GBrowserIsCompatible()) {
var maploaded = false
var maploadTimer = 0
function load(){
//fire the 'loading' message
checkGoogleMap()
// Global scope
var G = google.maps;
var map;
var api = new NauticalChartsAPI();
/**
* Initialize the Google map.
*/
}
function init() {
/**
* boiler-plate Google Maps code.
*/
var latlng = new G.LatLng(29.37895317, -91.75290604);
var myOptions = {
zoom: 9,
center: new G.LatLng(29.37895317, -91.75290604),
mapTypeId: G.MapTypeId.ROADMAP,
mapTypeControl: true,
mapTypeControlOptions: {
style: G.MapTypeControlStyle.DROPDOWN_MENU
},
};
var map = new G.Map(document.getElementById("map_canvas"),myOptions);
map.addListener('click', (function () {
var converter = function (value, labels) {
var sign = value < 0 ? 0 : 1;
var abs = Math.abs(Math.round(value * 1000000));
var dec = abs % 1000000 / 1000000;
var deg = Math.floor(abs / 1000000);
var min = Math.floor(dec * 60);
var sec = (dec - min / 60) * 3600;
var result = '';
result += deg;
result += "\u00B0";
result += ' ';
result += (min < 10 ? '0' : '') + min;
result += "\u0027";
result += ' ';
result += sec.toFixed(1) * 10;
result += "\u0022";
result += labels[sign];
return result;
};
var marker;
var popup;
return function (e) {
var latLng = e.latLng;
if (!marker) {
marker = new google.maps.Marker({
map: map
});
popup = new google.maps.InfoWindow();
marker.addListener('click', function () {
if (popup && !popup.getMap()) {
popup.open(map, marker);
}
})
} else {
popup.close();
}
var content = converter(latLng.lat(), ['S', 'N']) + '<br>' + converter(latLng.lng(), ['W', 'E']);
marker.setTitle(content);
marker.setPosition(latLng);
popup.setContent('<p>' + content.replace(/ /g, ' ') + '</p>');
popup.open(map, marker);
};
})());
api.setMap(map);
if( api.isLoaded() ) {
// Select the panel we want.
var panel = api.getPanelByFileName('1116A_1');
// Compute and set center/zoom for optimal map coverage
var bounds = panel.getBounds();
map.setCenter(bounds.getCenter());
// add panel as a tile layer
var panelMapType = panel.getTileLayer();
//alert(overlay.setOpacity(.2));
//overlay.setOpacity(1);//this doesn't work!
map.overlayMapTypes.insertAt(0,panelMapType);
}
//add the 'loaded' listener
GEvent.addListener(map, 'tilesloaded', function(){
maploaded = true
});
//add the 'map type changed' listener
GEvent.addListener(map, 'maptypechanged', function(){
resetCheckGoogleMap()
});
//add the 'zoom level changed' listener
//GEvent.addListener(map, 'zoomend', function(){
//resetCheckGoogleMap()
//});
}
function checkGoogleMap() {
//increment the timer every second
maploadTimer = maploadTimer + 1
//specify the target element for our messages
var msg = document.getElementById('msg')
if (maploaded == false) {
//if we dont have a fully loaded map - show the message
$("#msgContainer").slideDown("fast")
//for the first 5 tries, show this message
if (maploadTimer < 5) {
msg.innerHTML = 'Loading map images from Google Maps...';
}
//loop it
setTimeout('checkGoogleMap()',1000);
} else {
//otherwise, show 'loaded' message then hide the message after a second
msg.innerHTML = 'Map loaded.'
maploadTimer = 0;
setTimeout('hideMsg()',1000);
}
//if the timer get up to 20, show a different message
if (maploadTimer >= 20 && maploadTimer <40 ) {
msg.innerHTML = 'Sorry about the wait - your connection to Google Maps is a little slow.';
}
//if it gets to 40 show another different message with a reload link (for what its worth!)
if (maploadTimer >= 40) {
msg.innerHTML = 'Hmmm, still waiting! You can wait a bit longer or you could try reloading the map.';
}
}
function hideMsg() {
$("#msgContainer").slideUp("fast")
}
function resetCheckGoogleMap() {
maploaded = false
maploadTimer = 0;
checkGoogleMap();
}
}
else
alert('api is not loaded!');
}
</script>
<style>
.map_canvas {
position:absolute;
top:50px;
width:100%;
height:90%;
}
}
#msgContainer {
width:100%;
height:30px;
line-height:30px;
background:#FFFFCC;
position:absolute;
z-index:100;
left:0;
top:0;
display:none;
font-size:1.2em;
border-bottom:#FFCC66 1px solid;
}
#msg {
padding-left:10px;
text-align:center;
}
</style>
</head>
<body onLoad="init()">
<div id="msgContainer">
<div id="msg"></div>
</div>
<div id="map_canvas" style="width:100%; height:90%;"></div>
</body>
</html>
GEvent is Google Maps Javascript API v2 syntax, if you are using v3 to equivalent is google.maps.event
//add the 'loaded' listener
GEvent.addListener(map, 'tilesloaded', function(){
maploaded = true
});
//add the 'map type changed' listener
GEvent.addListener(map, 'maptypechanged', function(){
resetCheckGoogleMap()
});
should be:
//add the 'loaded' listener
google.maps.event.addListener(map, 'tilesloaded', function(){
maploaded = true
});
//add the 'map type changed' listener
google.maps.event.addListener(map, 'maptypechanged', function(){
resetCheckGoogleMap()
});

Google maps v3: clustering with custom markers

I'm trying to use MarkerClusterer to clusterize the markers on my map.
The problem is that I'm not using default markers (google.maps.Marker), but instead a custom class which hinerits from google.maps.OverlayView.
Unfortunately it seems that the library has been developed assuming the use of basic markers, in fact I get errors because my class does not implement methods defined in google.maps.Marker.
Is it possible to use the MarkerClusterer by keeping my custom markers?
EDIT: it was a lot easier than I expected, I solved by implementing 2 methods in my custom class:
setVisible() and getPosition()
in order to help others the following is my complete interface (without full implementation):
BFPushpin = function(config)
{
this.setMap(config.map);
this.set("position", config.position);
// other settings...
};
// my class extends google.maps.OverlayView
BFPushpin.prototype = new google.maps.OverlayView();
BFPushpin.prototype.getBounds = function()
{
return new google.maps.LatLngBounds(this.position, this.position);
};
BFPushpin.prototype.getPoint = function()
{
var bounds = this.getBounds();
var projection = this.getProjection();
var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());
var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());
return new google.maps.Point(sw.x, ne.y);
};
BFPushpin.prototype.getSuperContainer = function()
{
var panes = this.getPanes();
return jQuery(panes ? panes.overlayImage : "");
};
BFPushpin.prototype.getContainer = function()
{
// return inner container
};
BFPushpin.prototype._generatePopupContent = function()
{
// return markup for the popupwindow
};
BFPushpin.prototype._addListeners = function()
{
// add handlers for the pushpin
};
BFPushpin.prototype.onAdd = function()
{
// customize content here
};
BFPushpin.prototype.onRemove = function()
{
// remove pin container here
};
BFPushpin.prototype.draw = function()
{
// set display style here
};
BFPushpin.prototype.setVisible = function(visible)
{
// set display block or hidden
};
BFPushpin.prototype.getPosition = function()
{
return this.position;
};
Or just define the functions that the MarkerClusterer expects on the marker. setMap and getPosition() and some other ones.
You should probably define your new marker class in such a way that it also inherits from google.maps.Marker (i.e. that it implements its interface). It is logical that MarkerClusterer uses this interface - it has to suppose the markers are markers in order to work with them :-)
Hopefully this will also help people trying to get this solution to work. Thanks #daveoncode for the example. I was able to modify it to get it working for me:
renderMap() {
const mapProperties = {
center: new google.maps.LatLng(34.0234, -84.6155),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
this.map = new google.maps.Map(this.mapElement.nativeElement, mapProperties);
let markers = [];
for (let i=0; i<this._sitesList.length; i++) {
let bounds = new google.maps.LatLngBounds(
new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon)
);
let position = new google.maps.LatLng(this._sitesList[i].lat, this._sitesList[i].lon);
let html = this.makeHtmlForSitePanel(i, this._sitesList[i]); // I have a function to return html for my OverlayView panels here.
markers.push( this.generateSitePanel(bounds, html, this.map, position) );
}
var markerCluster = new MarkerClusterer(this.map, markers, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
}
generateSitePanel(bounds, html, map, position) {
SitePanel.prototype = new google.maps.OverlayView();
function SitePanel (bounds, html, map, position) {
this.bounds_ = bounds;
this.set('position', position);
this.html_ = html;
this.map_ = map;
this.div_ = null;
this.setMap(map);
}
SitePanel.prototype.getBounds = function() {
return new google.maps.LatLngBounds(this.position, this.position);
};
SitePanel.prototype.getPoint = function() {
var bounds = this.getBounds();
var projection = this.getProjection();
var sw = projection.fromLatLngToDivPixel(bounds.getSouthWest());
var ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());
return new google.maps.Point(sw.x, ne.y);
};
SitePanel.prototype.getSuperContainer = function(){
var panes = this.getPanes();
return $(panes ? panes.overlayImage : '');
};
SitePanel.prototype.getContainer = function()
{
// return inner container
// I don't have anything for this one
};
SitePanel.prototype.getPosition = function() {
return this.position;
};
SitePanel.prototype.onAdd = function() {
var div = document.createElement('div');
div.className = 'tooltip-container-';
div.innerHTML = this.html_;
div.style.position = 'absolute';
this.div_ = div;
var panes = this.getPanes();
panes.overlayImage.appendChild(div);
};
SitePanel.prototype.draw = function() {
var overlayProjection = this.getProjection();
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
var div = this.div_;
div.style.left = sw.x + 'px';
div.style.top = ne.y + 20 + 'px';
};
SitePanel.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
return new SitePanel(bounds, html, map, position);
}

Google map with route-trace loading data instead of adding it on click

In this map
http://econym.org.uk/gmap/example_snappath.htm
source:
<script type="text/javascript">
//<![CDATA[
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(53.7877, -2.9832),13)
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
var dirn = new GDirections();
var firstpoint = true;
var gmarkers = [];
var gpolys = [];
var dist = 0;
GEvent.addListener(map, "click", function(overlay,point) {
// == When the user clicks on a the map, get directiobns from that point to itself ==
if (!overlay) {
if (firstpoint) {
dirn.loadFromWaypoints([point.toUrlValue(6),point.toUrlValue(6)],{getPolyline:true});
} else {
dirn.loadFromWaypoints([gmarkers[gmarkers.length-1].getPoint(),point.toUrlValue(6)],{getPolyline:true});
}
}
});
// == when the load event completes, plot the point on the street ==
GEvent.addListener(dirn,"load", function() {
// snap to last vertex in the polyline
var n = dirn.getPolyline().getVertexCount();
var p=dirn.getPolyline().getVertex(n-1);
var marker=new GMarker(p);
map.addOverlay(marker);
// store the details
gmarkers.push(marker);
if (!firstpoint) {
map.addOverlay(dirn.getPolyline());
gpolys.push(dirn.getPolyline());
dist += dirn.getPolyline().Distance();
document.getElementById("distance").innerHTML="Path length: "+(dist/1000).toFixed(2)+" km. "+(dist/1609.344).toFixed(2)+" miles.";
}
firstpoint = false;
});
GEvent.addListener(dirn,"error", function() {
GLog.write("Failed: "+dirn.getStatus().code);
});
}
else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
// This Javascript is based on code provided by the
// Community Church Javascript Team
// http://www.bisphamchurch.org.uk/
// http://econym.org.uk/gmap/
//]]>
</script>
You can click and add paths that trace routes.
I would like to use the trace-road-functionality, but pre-define the data using coordinates instead. How would I do this?

GLatLngBounds - wrong center and zoom level

I'm trying to use GLatLngBounds to make all the markers on the map visible. Below is a small example of what I'm doing.
INV.createMap = function(containerId) {
var map = null;
var geocoder = null;
var bounds = new GLatLngBounds();
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById(containerId), {
size: new GSize(600, 300)
});
map.setCenter(new GLatLng(54.729378425601766, 25.279541015625), 15);
map.addControl(new GSmallZoomControl());
geocoder = new GClientGeocoder();
}
return {
markAdress: function(address, infoContentHtml) {
if (map !== null && geocoder !== null) {
geocoder.getLatLng(address, function(point) {
if (point) {
var marker = new GMarker(point);
GEvent.addListener(marker, 'mouseover', function() {
if (!map.getInfoWindow().getPoint().equals(this.getLatLng())) {
this.openInfoWindowHtml(infoContentHtml);
}
});
map.addOverlay(marker);
bounds.extend(point);
}
});
}
},
finalize: function() {
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
}
};
};
Usage:
var m = INV.createMap('whatever');
var addresses = ...
for (var i = 0, l = addresses.length; i < l; i++) {
m.markAdress('address...', 'htmlInfo...');
}
m.finalize();
The problem is that the zoom level is completely wrong (waaay too zoomed out) and the markers appear on the left top corner of the map for some reason (but all of them are visible).
What am I doing wrong?
EDIT: Ignore this question. I've made a stupid mistake - I overlooked the fact that GClientGeocoder makes asynchronous requests so the finalize() method is called too early.
The last argument of the function call below specifies the zoom level:
map.setCenter(new GLatLng(54.729378425601766, 25.279541015625), 15);
This article talks a bit about zooming. So the zooming level is a bit too high.
Further this tutorial tells you how to fit the map zooming to properly display a set of markers.
Hope this helps

Categories

Resources