Perspective Map

As showed here https://demo.inductiveautomation.com/data/perspective/client/OnlineDemo/feature/realtime/maps

Ignition has built-in Map Support for OpenStreetMap and Google Maps. I have configured the center position, but I don’t understand how add pins, shapes, and layers, any suggestion?

1 Like

The required fields show up for the many properties when you add an array element to that property, which should be enough to get started. For example, if you go to props.layers.ui.marker and add an element for marker, it will go from this:

To this:

Our implementation of maps is from Leaflet, so if you want a deep dive explanation of all the properties, you can see the full documentation from Leaflet here Leaflet Docs. I would suggest that if you run into properties that don’t immediately make sense to check out their docs first.

3 Likes

Thank a lot, I read the documentation from Leaflet.
If I want to define markers from a query, I suppose that I must transform each row in the query result in a marker object with a specific shape (like in property editor), but how can I do it from script?

I’m trying with a transform script:

value_objects = []
py_value = system.dataset.toPyDataSet(value)
for row in py_value:
	value_objects.append({'lat':row['latitude'], 'lng':row['longitude']})
return value_objects

but doesn’t works.

In order to append directly to the marker array, you will have to define the rest of the required key/values and objects for the individual markers. Your script creates the lat and lng properties, but is missing other important parts. I’ve written a sample script that mimics the default marker object.

	markers = []
	pydata = system.dataset.toPyDataSet(value)
	tooltip = {'enabled':False,'content':'','direction':'auto','permanent':False,'sticky':False,'opacity':1}
	icon = {'path':'','size':{}}
	popup = {'enabled':False,'content':'','width':{'max':300,'min':50},'height':{},'pan':{'auto':True},'closeButton':True,'autoClose':True,'closeOnEscapeKey':True}
	for row in pydata:
		markers.append({'lat':row['latitude'],'lng':row['longitude'],'opacity':1,'riseOnHover':False,'riseOffset':250,'icon':icon,'tooltip':tooltip,'popup':popup})
	return markers

You probably can strip away some of the unused variables, but this will give you all the options we would normally start a new marker with and can be edited to fit better with your project.

2 Likes

I'm trying to customize icon, I uploaded image to the Image Management tool in a new folder and I'm using that in image component (source = "/system/images/newFolder/logo.png" and mode = fill)

How can I do the same thing with marker's icon ?

icon = {'path':'/system/images/newFolder/logo.png','size':{}} doesn't work, this is the error:

[Browser Events Thread] INFO Perspective.Designer.BrowserConsole - onerrorLogger: {"msg":"Uncaught Exception","errorMsg":"Script error.","url":"","line number":0,"column":0}
[Browser Events Thread] INFO Perspective.Designer.BrowserConsole - Uncaught Error: iconUrl not set in Icon options (see the docs).

Map marker icons currently don't work as we expect, so you will have to skip this part for now. When they get working though, they will be using the Icon paths we have defined, not the regular Image Management image paths you may be used to from Vision.

The difference is best described here:

Ok, so I will have to create a svg file with the icons and I will have to copy this file in the gateway’s folder data\modules\com.inductiveautomation.perspective\icon

Correct, but like I said it is not currently working. There is an outstanding bug for that issue.

1 Like

Any news to the bug fix?

Given the above example, if I create the appropriate key/values in I should think I'd be able to set it like this:

self.getSibling("Map").layers.ui.marker = markers

However this generates the error:

AttributeError: 'com.inductiveautomation.perspective.gateway.script' object has no attribute 'layers'

The script is inside a button action on the same level as the map component.

After a little more examination I find that the type of the object accessed via self.getSibling("Map") is:

com.inductiveautomation.perspective.gateway.script.ComponentModelScriptWrapper$SafetyWrapper

This seems to be the case with any object I try to access. However as far as I can tell I'm doing what the documentation suggests: https://docs.inductiveautomation.com/display/DOC80/Perspective+Scripting

It appears that this has been fixed as of 12/21. It will expect the path {icon_library_name}/{icon_name} like the normal icon component.

When locating component attributes, you must include the sub category that the property is in, for layers property in a map that is PROPS. So it would look like:

self.getSibling("Map").props.layers.ui.marker

It looks like the Perspective documentation for that is not correct in their examples, I'll let the documentation guys know.

Along those same lines: When I take the existing markers from the Map like this:

markers = self.getSibling("Map").props.layers.ui.marker

I can view and manipulate. However, the append method doesn't seem to work. For example, I'm reading an array with a length of 2 (i.e. two markers) and when I try to appends like this (from the example above):

markers.append({'lat':40.413521,'lng':-91.401863,'opacity':1,'riseOnHover':False,'riseOffset':250,'icon':icon,'tooltip':tooltip,'popup':popup})

I get the error:

java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2

However, if I start with an empty list I can append. The Map component appears to be using a PyArray however according to the documentation I've seen this should behave like the list's append method. I must be missing something.

About the marker Icons: I can change the marker icon and size, however seem to be unable to change the color.

icon = {'path':'material/location_on','size':{"width":40,"height":60},'color':'red'}

As far as the color property goes, I've tried RGB, Hex integer and java.awt.Color values all seem to be ignored. I did notice that the Icon component has a color property that seems to be unicode.

@WildeKurt Were you able to manipulate the marker color?

Since you have had experience with map component, can you answer this question?

6 posts were split to a new topic: Create binding programatically

This code worked for me.
Is there any way, a conditional statement can be run inside the 'for' loop?
Like changing the color of the marker according to the value of row['variable'].

I found a way. using one line if condition./
'color':'#1560bd' if status == True else '#888888'

You can probably omit == True.
if status will return a True or False by itself.

1 Like

Thanks. Am I able to run a query inside the marker?
What if I need to display more info in every marker from another database?

It sounds like we're wandering off-topic here. Open a new question and explain what you're trying to do. (I don't understand it from your post above.)