OpenLayers Markers with custom Text / Label - javascript

I have "N" markers on an Openlayers map and I need to "label" these markers (Meaning: Put a text in/on them)
I have tried several ways but still couldn't achieve what I need.
My JS code snippet (Removed some irrevelant stuff from the code):
function getWeatherInfo(){
if(wheatherOfCitiesMarkerLayer == null){
wheatherOfCitiesMarkerLayer = new OpenLayers.Layer.Markers("WeatherMarkerLayer");
map.addLayer(wheatherOfCitiesMarkerLayer);
}
$.getJSON(qryPointResultListForAllCities(), function(data) {
if(data!= null){
var size = new OpenLayers.Size(60,45);
var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
for(var i = 0; i < data.pr.length; i ++){
// Create markers by using the returned data from the server
//...
//... Removed some irrevelant stuff
var lat = data.pr[i].la;
var lon = data.pr[i].lo;
var infos = data.pr[i].info.infos;
var infop = data.pr[i].info.infop;
var infocc = data.pr[i].info.infocc;
var icon = new OpenLayers.Icon('my_marker_img.png',size,offset);
location = new OpenLayers.LonLat(lon, lat);
location = transformFromWGS1984ToSphericalMercator(location.clone());
marker = new OpenLayers.Marker(location,icon.clone());
wheatherOfCitiesMarkerLayer.addMarker(marker);
}
}
}
}
What I need to do is put a label or text in/on each marker on the map.

Since you are taking marker data from server anyway, what you can do is, create a layer in a map file with just the label class defined and add it on your marker layer as a overlay.
Hope this helps.

Instead of adding text (or label) to a marker, you can add a marker to a label.
This is done by creating a new text file with the location, title, description and path to your icon (not required, it will use the default if none is set). For example,
if you want to place two markers on the map, the text file may look like this
point title description icon
10,99 An labeled marker with default image
12,34 Another marker This is my label text http://example.com/marker.png
Please note that there should be tabs between the names and parameters, not spaces. There is also a tab at the end of the second line where no icon is given.
Save this file somewhere on your site and put this code where your layers are being initialized.
var textl = new OpenLayers.Layer.Text("text", {location : "data_dile.txt"});
map.addLayer(textl);
The text file may be created dynamically though server-side languages, such as PHP.
There is an online example here.

Related

show popups correctly with external hyperlinks in openlayers 4

I have an openlayers map that loads a couple of kml files containing about 120 polygon placemarks each. As they're too many to show a popup for each, I had to create an outside-map menu, so the user can click on any one of these features and see it's info / location.
I use this function to create the outside-map menu, containing all the features:
vEnergeticos.getSource().on('change', function(evt){
var source = evt.target;
if (source.getState() === 'ready') {
var energeticos = source.getFeatures();
for (var i in energeticos) {
var figura = energeticos[i].getGeometry().getExtent();
var myCenter = ol.extent.getCenter(figura);
$("#containerLeft").append("<a href=javascript:showMenuPopup(" + myCenter + "," + energeticos[i].get('ID') + ")>" + energeticos[i].get('name') + "</a><br>");
}
}
});
and then when the user clicks on any of these options, this function is called:
function showMenuPopup(xx, yy, theID){
var myPixel = map.getPixelFromCoordinate([xx, yy]);
var elNombre = "";
var laDescripcion = "";
map.forEachFeatureAtPixel(myPixel, function(feature, layer) {
if (feature.get('ID') == theID){
elNombre = feature.get('name');
laDescripcion = feature.get('description');
}
});
popupTitle.innerHTML = elNombre;
popupContent.innerHTML = laDescripcion;
overlay.setPosition([xx,yy]);
}
This works in some situations, however, when the selected feature is outside of the current map view, the map relocates successfully (overlay.setPosition([xx,yy]);), the popup is shown, but the popup is empty. If the feature is visible when the user clicks from the left menu, then the popup is shown correctly.
Just to be clear enough, imagine you're seeing a map where you can see part of Europe, and then you click on some item located in Canada (using the off-map menu), you'll see the map relocates in Canada, but the popup that is shown is empty. If you click again on that very same off-map link, or any other feature that is visible at that location/zoom view, then the popup is shown correctly.
I tried to use the "moveend (ol.MapEvent)" in order to fix this, so the popup was loaded after the map is relocated, but it didn't work for me. The moveend event is called before the map starts to move using overlay.setPosition([xx,yy]), and I haven't been able to find some other "after-relocation" event that I could use.
I've been struggling with this for many days now, so any help will be really appreciated.
Regards!!
The problem is that the features outside of the current map view are not "AtPixel", so you won't catch them with map.forEachFeatureAtPixel.
I suggest you to avoid passing coordinates to showMenuPopup: you just need the feature id, than you can retrieve the feature's coordinates inside showMenuPopup.
$("#containerLeft").append("<a href=javascript:showMenuPopup('" + energeticos[i].getId() + "')>" + energeticos[i].get('name') + "</a><br>");
Then
function showMenuPopup(featureId){
var feature = vEnergeticos.getSource().getFeatureById(featureId);
var elNombre = feature.get('name');
var laDescripcion = feature.get('description');
var figura = feature.getGeometry().getExtent();
var myCenter = ol.extent.getCenter(figura);
popupTitle.innerHTML = elNombre;
popupContent.innerHTML = laDescripcion;
overlay.setPosition(myCenter);
}

Replacing a placeholder text label in a Google Docs table cell with a Google Drive image

I am trying to automate populating a report using only Google Apps. The sequence goes as followed:
Google Form > Google Sheets > Google Docs Template
The Google Form serves the purpose to enter all details for the final report: A quality score (1, 2 or 3) and some text. In Google Sheets, the quality score gets transformed into a text based label (#good#, #ok#, #bad#).
I've found a script here on Stack Overflow that picks up a Google Doc Template and populates the placeholder labels (%placeholder%) with the values in the Google Sheet. However, I haven't been able to solve for replacing the quality score label with an image/icon (a green, orange and red icon) that I have in my Google Drive. I got as far as replacing the label with the icon's file name (e.g. icon-green.png), but not the icon itself. Good to know is that the quality score label is placed within a table cell.
I'm incredibly new to javascript and could really use your help! I've indicated in the code beneath where I'm stuck exactly (towards the end).
// Replace this with ID of your template document.
var TEMPLATE_ID = '1AatkH57Iq3FwmsvZkCMYddjACItWS_XuO9sCsfcaMso'
// You can specify a name for the new PDF file here, or leave empty to use the
// name of the template.
var DOC_FILE_NAME = 'First GA Doc Template Try'
/**
* Eventhandler for spreadsheet opening - add a menu.
*/
function onOpen() {
SpreadsheetApp
.getUi()
.createMenu('Create Doc')
.addItem('Create Doc', 'createDoc')
.addToUi()
} // onOpen()
/**
* Take the fields from the active row in the active sheet
* and, using a Google Doc template, create a Doc with these
* fields replacing the keys in the template. The keys are identified
* by having a % either side, e.g. %Name%.
*
* #return {Object} the completed Doc file
*/
function createDoc() {
if (TEMPLATE_ID === '') {
SpreadsheetApp.getUi().alert('TEMPLATE_ID needs to be defined in code.gs')
return
}
// Set up the docs and the spreadsheet access
var copyFile = DriveApp.getFileById(TEMPLATE_ID).makeCopy(),
iconGreen = DriveApp.getFileById('0B0C0sFLzFLyWOUVSeWxQa2o2MFE'),
copyId = copyFile.getId(),
copyDoc = DocumentApp.openById(copyId),
copyBody = copyDoc.getActiveSection(),
activeSheet = SpreadsheetApp.getActiveSheet(),
numberOfColumns = activeSheet.getLastColumn(),
activeRowIndex = activeSheet.getActiveRange().getRowIndex(),
activeRow = activeSheet.getRange(activeRowIndex, 1, 1, numberOfColumns).getValues(),
headerRow = activeSheet.getRange(1, 1, 1, numberOfColumns).getValues(),
columnIndex = 0
// Replace the keys with the spreadsheet values
for (;columnIndex < headerRow[0].length; columnIndex++) {
copyBody.replaceText('%' + headerRow[0][columnIndex] + '%',
activeRow[0][columnIndex])
}
copyBody.replaceText('#good#', iconGreen) // This is where I'm stuck..
copyFile.setTrashed(false)
SpreadsheetApp.getUi().alert('New Doc created in the root of your Google Drive')
} // createDoc()
If you want to insert the image into a Google Doc you will need to get it as a blob and call the insertImage function, something like this:
var blob = DriveApp.getFileById(id).getBlob(); // Replace id with the ID of your icon file.
// This is inserting it into a specific cell in an existing table.
var newImage = curTable.getRow(imgTargetRow).getCell(imgTargetCol).insertImage(0, blob);
// This sets the image height and width based on my table cell sizes, but if your icon is sized exactly right you won't need to do this
var h = newImage.getHeight();
var w = newImage.getWidth();
var w = ((w > h) ? 352 : 197); // Adjust for landscape or portrait images
var h = 264;
newImage.setHeight(h);
newImage.setWidth(w);

Google Maps V3 - Switching on/off groups of markers

I am currently trying to use Google Maps with a bunch of markers on it (extracted from a JSON data file). I want to be able to group the markers in one of two categories and be able to switch them off or on.
I am up to the point where the map is working, the pointers are showing and the switch buttons are flicking on and off - all that is left now is to add the markers to groups and bind the switch buttons to displaying/hiding the markers on the map.
I know that I can use marker.setVisible(false/true) but I'm not sure how or where to use it.
I am new to using Google Maps API v3 so any direction with this would be much appreciated.
I have setup a fiddle with what I have so far, you can see it here: https://jsfiddle.net/6n25g3n7/4/
You need to make your markers variable been access to your click event.
Code example:
var markers = [];
function addMarkerToMap(map, markerData){
for(var i = 0; i < markerData.length; i++){
// init marker
markers.push(marker); //push to marker's array
}
}
function clickEvent(){
for(var key in markers){
markers[key].setVisible(true/false);
}
}
fiddle: https://jsfiddle.net/6n25g3n7/5/ Sorry about code is a little bit mess.
If you have any question about code, please comment :)
This one has both markers turning on and off. Check the jsfiddle for all the changes. I had to re-structure some of your code.
function createSwitches(markers){
var html = '<div class="switches"><span class="switch-title">Show Me</span></div>';
// ADD YOU SWITCHES HERE!
// Make sure the same order as the google markers
var all_switches = [
{
html: '<span class="whats-on-wrapper"><span data-target="whats-on" class="switch switch-on">Item Group 2</span></span>',
},
{
html: '<span class="stand-wrapper"><span data-target="stand" class="switch switch-on">Item Group 1</span></span>',
}
];
// Add the main bar element
$('.map-container').prepend(html);
// Loop through all your switches and add them
// with the event
for (var i = 0; i < all_switches.length; i++) {
var element = $(all_switches[i]["html"]);
(function(index, element, markers) {
$(element).on('click', function () {
var this_marker = markers[index];
var current = String(this_marker.visible);
var toggle = ( current === "true") ? false : true;
this_marker.setVisible(toggle);
});
})(i, element, markers)
$('.switches').append($(element))
}
// Set the toggle animation
$('.switches .switch').click(function(){
$(this).toggleClass('switch-on');
$(this).toggleClass('switch-off');
});
}
https://jsfiddle.net/6n25g3n7/8/

Rename only visible layers in illustrator javascript

Super noob question. I found a code that renames my top level layers as "Frame 1, Frame 2, etc..." How can I have the rename apply ONLY to visible layers? Second question is how do I rename only a selected layer (whether it visible or not) to "Frame 1" or whatever I choose and not affect any other layers in the document?
Here is the code.
var doc = app.activeDocument;
idLayers(doc); // Rename layers
function idLayers(doc){
for(i=0;doc.layers.length>i;i++){
var currentLayer = doc.layers[i];
currentLayer.name= 'Frame '+(i+1);
}
}
Thank you so much for your help!
This can all be easily found in the illustrator scripting reference.
This script does both things you asked, just comment out the function call you don't want to run and put the layer prefix or name you want for the layer in the function call.
var doc = app.activeDocument;
idLayers("Frame "); // Rename visible layers
renameSelectedLayer("Active"); // Rename active layers
// Hidden layers will be skipped and not counted
function idLayers(prefix){
var counter = 1;
for(i=0;doc.layers.length>i;i++){
var currentLayer = doc.layers[i];
// if layer is visible...
if (currentLayer.visible) {
currentLayer.name= prefix + counter;
counter++;
}
}
}
function renameSelectedLayer(layerName){
doc.activeLayer.name = layerName
}

events.register is auto-executing the event being registered

I am trying to attach a Popup for each marker (I am using OpenLayers and OpenStreetMaps for this). Each marker is being registered an event 'click' that will show it's corresponding popup.
However, what it does is to just execute all the popups upon start-up instead of waiting for a given marker click.
There are approximately 1000 markers so I am using this loop to populate the markers and popups (which are hidden when created):
for (var i = 0; i < data.length; i++)
{
if (i == 1) {
var lonLat = new OpenLayers.LonLat(data[i].Lon, data[i].Lat).transform(fromProjection, toProjection);
var zoom = 5;
map.setCenter(lonLat, zoom);
}
var lonLat = new OpenLayers.LonLat(data[i].Lon, data[i].Lat).transform(fromProjection, toProjection);
AddingPopup(lonLat);
AddingMarker(i, lonLat);
And these are my functions for creating both:
function AddingMarker(i, lonLat) {
var marker = new OpenLayers.Marker(lonLat);
markers.addMarker(marker);
marker.events.register('click', marker, PopupsShow(i));
};
function AddingPopup(lonLat) {
var popup = new OpenLayers.Popup("Popup", lonLat, null, "text", true);
map.addPopup(popup);
popup.hide();
};
And this is the function that is being auto-fired for all markers upon execution:
function PopupsShow(i) {
map.popups[i].show();
};
What am I missing here. Why is the PopupsShow function started upon execution and it's not waiting for the marker to be clicked. I've been looking around for answers, but nothing seems to help.
Thanks!
I have figured it out:
We cannot register an event using marker.events.register("click", marker, PopupsShow(i))
Instead we need to call it like this: marker.events.register("click", marker, PopupsShow)
And since we need the i we can call it like this:
marker.events.register("click", marker, function () {
map.popups[i].show();
});
The event handler can actually get an argument (event) which is the idiomatic way of performing this. Also it is considered best to bind the handler to a layer instead of each marker.
markerLayer.events.register('click', marker,
function(event) {
var feature = event.feature;
/* make popup appear */
});
The way to make a popup varies to meet your needs, but usually the popup is created on demand here rather than pregenerating and calling show.

Categories

Resources