Optimization of Dijkstras - dijkstra

I would like some help to optimize this code. In the part where I
initialize all the ArrayLists, it feels insufficient that I have to set
them to default values for the size of the path ArrayList, since I am only
interested for the path from the source node to the destination node. Do you
guys have any idea on how to fix this?
Cheers!
//Shortest path algorithm
public void shortestPath(String source, String end){
/*
* Init the vertices, init the distances
* Set the distance from the start node to itself to 0
*/
copy = g.getMap();
initArrays(copy);
holdCost.add(agent.get(source), 0);
pq.insert(new Vertex(source, 0));
while(!pq.isEmpty()){
Vertex v = pq.getRoot();
pq.delete(pq.getRoot());
visited.set(agent.get(v), true);
for(Edge e : copy.get(v)){
if(!visited.get(agent.get(e))){
if(holdCost.get(agent.get(e)) > (holdCost.get(agent.get(v))
+ e.getWeight())){
holdCost.set(agent.get(e), (holdCost.get(agent.get(v))
+ e.getWeight()));
pq.insert(new Vertex(path.get(agent.get(e)),
holdCost.get(agent.get(e))));
cost.add(holdCost.get(agent.get(e)));
}if(visited.get(agent.get(end))){
break;
}
}
}
}
}
//Initiliaze of distance, nodes etc
public void initArrays(HashMap<String, ArrayList<Edge>> h){
for(String s : h.keySet()){
path.add(s);
holdCost.add(path.indexOf(s), Integer.MAX_VALUE);
visited.add(path.indexOf(s), false);
agent.put(s, path.indexOf(s)); //easy to get the same index as vertices, distances etc
}
}

Related

What's the best way to save terraindata to file in Runtime?

My game lets the user modify the terrain at runtime, but now I need to save said terrain. I've tried to directly save the terrain's heightmap to a file, but this takes almost up to two minutes to write for this 513x513 heightmap.
What would be a good way to approach this? Is there any way to optimize the writing speed, or am I approaching this the wrong way?
public static void Save(string pathraw, TerrainData terrain)
{
//Get full directory to save to
System.IO.FileInfo path = new System.IO.FileInfo(Application.persistentDataPath + "/" + pathraw);
path.Directory.Create();
System.IO.File.Delete(path.FullName);
Debug.Log(path);
//Get the width and height of the heightmap, and the heights of the terrain
int w = terrain.heightmapWidth;
int h = terrain.heightmapHeight;
float[,] tData = terrain.GetHeights(0, 0, w, h);
//Write the heights of the terrain to a file
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
//Mathf.Round is to round up the floats to decrease file size, where something like 5.2362534 becomes 5.24
System.IO.File.AppendAllText(path.FullName, (Mathf.Round(tData[x, y] * 100) / 100) + ";");
}
}
}
As a sidenote, the Mathf.Round doesn't seem to influence the saving time too much, if at all.
You are making a lot of small individual File IO calls. File IO is always time consuming and expensive as it contains opening the file, writing to it, saving the file and closing the file.
Instead I would rather generate the complete string using e.g. a StringBuilder which is also more efficient than using something like
var someString
for(...)
{
someString += "xyz"
}
because the latter always allocates a new string.
Then use e.g. a FileStream and StringWriter.WriteAsync(string) for writing async.
Also rather use Path.Combine instead of directly concatenating string via /. Path.Combine automatically uses the correct connectors according to the OS it is used on.
And instead of FileInfo.Directory.Create rather use Directory.CreateDirectory which doesn't throw an exception if the directory already exists.
Something like
using System.IO;
...
public static void Save(string pathraw, TerrainData terrain)
{
//Get full directory to save to
var filePath = Path.Combine(Application.persistentDataPath, pathraw);
var path = new FileInfo(filePath);
Directory.CreateDirectory(path.DirectoryName);
// makes no sense to delete
// ... rather simply overwrite the file if exists
//File.Delete(path.FullName);
Debug.Log(path);
//Get the width and height of the heightmap, and the heights of the terrain
var w = terrain.heightmapWidth;
var h = terrain.heightmapHeight;
var tData = terrain.GetHeights(0, 0, w, h);
// put the string together
// StringBuilder is more efficient then using
// someString += "xyz" because latter always allocates a new string
var stringBuilder = new StringBuilder();
for (var y = 0; y < h; y++)
{
for (var x = 0; x < w; x++)
{
// also add the linebreak if needed
stringBuilder.Append(Mathf.Round(tData[x, y] * 100) / 100).Append(';').Append('\n');
}
}
using (var file = File.Open(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
using (var streamWriter = new StreamWriter(file, Encoding.UTF8))
{
streamWriter.WriteAsync(stringBuilder.ToString());
}
}
}
You might want to specify how exactly the numbers shall be printed with a certain precision like e.g.
(Mathf.Round(tData[x, y] * 100) / 100).ToString("0.00000000");

Unity / Search closes Object from a List by tag

I have a Problem to find the closest Object in my List.
There are three types with the tags (Food, Stone and Wood).
I spawn them at the beginning , some for each type, if i found some Resources, they're not hidden anymore, and i add them to the List that a Worker goes to them and harvests them.
So Later in the Game, for expample
i found 3 Stone Resources, then worker should harvest the closest one first everytime....
but i don't know how to iterate throw a Loop only to search for the Tags and how to get the position of the closest one.
Here is some code of the Method that i wrote:
void FindNearestFoodRessource()
{
for (int i = 0; i < gameController.discoveredRessources.Count; i++)
{
//float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
GameObject nearestFoodRessource = GameObject.FindGameObjectWithTag("Food");
}
}
First thing first - don't use FindGameObject**** in frequently called methods, it is very expensive.
About your problem - just check tag and distance of all the resources:
float minDist = Vector3.Distance(gameController.discoveredRessources[0].transform.position, transform.position);
int minDistIndex = 0;
for (int i = 1; i < gameController.discoveredRessources.Count; i++)
{
if (gameController.discoveredRessources[i].gameObject.CompareTag("Food"))
{
float dist = Vector3.Distance(gameController.discoveredRessources[i].transform.position, transform.position);
if (dist < minDist)
{
minDist = dist;
minDistIndex = i;
}
}
}
//Now you can move to gameController.discoveredRessources[minDistIndex]
Also you can store all the food/stones/wood in the separate lists when you find it
Using Linq Where and this usefull extension method MinBy
using System;
using System.Collections.Generic;
using System.Linq;
public static class Linqextensions
{
public static T MinBy<T, R>(this IEnumerable<T> en, Func<T, R> evaluate) where R : IComparable<R>
{
return en.Select(t => new Tuple<T, R>(t, evaluate(t)))
.Aggregate((max, next) => next.Item2.CompareTo(max.Item2) < 0 ? next : max).Item1;
}
}
(simply copy that code somwhere into your project) you could do it in "one" line
var closestItem = gameController.discoveredRessources
// this is a filter only selecting the ones with tag = "Food"
.Where(obj => obj.CompareTag("Food"))
// this returns you the item from the list with the lowest distance
.MinBy(obj => Vector3.Distance(obj.transform.position, transform.position));

Load the graph from the titan db for a specified depth in a single or efficitent query

We are using titan db to store the graph infomation. we have cassandra + es as backend storage and index. We are trying to load the graph data to represent the graph in the webui.
This is the approach i am following.
public JSONObject getGraph(long vertexId, final int depth) throws Exception {
JSONObject json = new JSONObject();
JSONArray vertices = new JSONArray();
JSONArray edges = new JSONArray();
final int currentDepth = 0;
TitanGraph graph = GraphFactory.getInstance().getGraph();
TitanTransaction tx = graph.newTransaction();
try {
GraphTraversalSource g = tx.traversal();
Vertex parent = graphDao.getVertex(vertexId);
loadGraph(g, parent, currentDepth + 1, depth, vertices, edges);
json.put("vertices", vertices);
json.put("edges", edges);
return json;
} catch (Throwable e) {
log.error(e.getMessage(), e);
if (tx != null) {
tx.rollback();
}
throw new Exception(e.getMessage(), e);
} finally {
if (tx != null) {
tx.close();
}
}
}
private void loadGraph(final GraphTraversalSource g, final Vertex vertex, final int currentDepth,
final int maxDepth, final JSONArray vertices, final JSONArray edges) throws Exception {
vertices.add(toJSONvertex));
List<Edge> edgeList = g.V(vertex.id()).outE().toList();
if (edgeList == null || edgeList.size() <= 0) {
return;
}
for (Edge edge : edgeList) {
Vertex child = edge.inVertex();
edges.add(Schema.toJSON(vertex, edge, child));
if (currentDepth < maxDepth) {
loadGraph(g, child, currentDepth + 1, maxDepth, vertices, edges);
}
}
}
But this is taking a bit lot of time for the depth 3 when we have more number of nodes exist in the tree it is taking about 1 min to load the data.
Please help me are there any better mechanisms to load the graph efficiently?
You might see better performance performing your full query across a single traversal execution - e.g., g.V(vertex.id()).outV().outV().outE() for depth 3 - but any vertices with very high edge cardinality are going to make this query slow no matter how you execute it.
To add to the answer by #Benjamin performing one traversal as opposed to many little ones which are constantly expanding will indeed be faster. Titan uses lazy loading so you should take advantage of that.
The next thing I would recommend is to also multithread each of your traversals and writes. Titan actually supports simultaneous writes very nicely. You can achieve this using Transactions.

jsoup equivalent of DOM Range operations like extractContents() etc

I'm trying to do extracting and replacing equivalents of JavaScript DocumentFragments through jsoup DOM model.
Does anyone have some ready to use code to emulate DOM Range selection and operations on it? I would like to select a range of text, which can possibly pass through multiple inline nodes (such as <a>, <span> etc.), start or end in the middle of such inline nodes etc. In JavaScript it's easy with Range operations, extracting a DocumentFragment form it, surrounding it etc. I guess JavaScript Range is splitting the inner nodes as needed to handle such extraction and insertion back correctly. How would I do this with jsoup in Java?
Edit: Just thinking out loud how to do this - probably would need to search for the "peak" element within my range, then go to both start and end of the range and "elevate" them to the "peak level" by jumping up to the parent if my start is the child no. 0, or else splitting the element children list just before the range start element... If there is such a code ready, I'd rather re-use it, else will have to write it from scratch.
Update Dec. 18, 2015: Posted my answer with the working code I developed, see below.
Two points:
JSoup offers some methods for manipulating text nodes as String object.
Java and its ecosystem offer powerful apis for manipulating String objects.
You may try to find your way with the two above options before writing DOM Range operations from scratch.
Here are some methods from the JSoup API:
Element#text()
Gets the combined unencoded text of this element as String.
Excerpt from API:
Given HTML <p>Hello <b>there</b> now! </p>, p.text() returns "Hello there now!"
Element#text(String) Replace the current text of this element with the passed unencoded one.
Element#ownText Gets the unencoded text of this element only without text of all children.
Excerpt from API:
For example, given HTML <p>Hello <b>there</b> now!</p>, p.ownText() returns "Hello now!", whereas p.text() returns "Hello there now!". Note that the text within the b element is not returned, as it is not a direct child of the p element.
You may find also useful these two recipes:
Extract attributes, text, and HTML from elements
Setting the text content of elements
Here is my promised code for wrapping an arbitrary range of DOM body into an arbitrary html tag for easy extraction, moving, replacement, copy/paste like operations etc.
Update Dec. 19, 2015 Added TextNode splitting in the middle of text by means of wrapRange() method variant with optional offsets into the text node where the range should start or end. Now arbitrary copy/paste/move within jsoup DOM model are possible.
TODO: (for myself or some other good soul)
Write a sample project demonstrating this, plus a number of test cases, and post to GitHub. No time for this now, but seems to work fine in my app (processing HTML code from web pages and ebooks for reading aloud with TTS - see #Voice Aloud Reader app in Google Play)
The RangeWrapper.java module:
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.parser.Tag;
import java.util.ArrayList;
/**
* Created by greg on 12/18/2015.
*/
public class RangeWrapper {
/**
* Wrap the supplied HTML around the "range" from startEl to endEl.*
* #param startEl the first element to be included into the range
* #param endEl the last element to be included into the range
* #param html HTML to wrap around this element, e.g.
* {#code <span class="head"></span>}. Can be arbitrarily deep.
* #return the wrapping element
*/
public static Element wrapRange(Node startEl, Node endEl, String html) {
if (startEl == endEl) { // special case
return (Element) startEl.wrap(html).parentNode();
}
int startDepth = NodeWalker.getNodeDepth(startEl);
int endDepth = NodeWalker.getNodeDepth(endEl);
int minDepth = getRangeMinDepth(startEl, endEl);
int n;
while (startDepth > minDepth) {
Element parent = (Element)startEl.parentNode();
if ((n = startEl.siblingIndex()) > 0) {
// splitting the parent
ArrayList<Node> children = new ArrayList<Node>(parent.childNodes());
Element parent2 = new Element(Tag.valueOf(parent.tagName()), parent.baseUri(), parent.attributes());
parent.after(parent2);
for (int i = n; i < children.size(); i++)
parent2.appendChild(children.get(i));
startEl = parent2;
} else {
startEl = parent;
}
startDepth--;
}
while (endDepth > minDepth) {
Element parent = (Element)endEl.parentNode();
if ((n = endEl.siblingIndex()) < parent.children().size()-1) {
// splitting the parent
ArrayList<Node> children = new ArrayList<Node>(parent.childNodes());
Element parent2 = new Element(Tag.valueOf(parent.tagName()), parent.baseUri(), parent.attributes());
parent.before(parent2);
for (int i = 0; i <= n; i++)
parent2.appendChild(children.get(i));
endEl = parent2;
} else {
endEl = parent;
}
endDepth--;
}
// Now startEl and endEl are on the same depth == minDepth.
// Wrap the range with our html string
Element range = (Element) startEl.wrap(html).parentNode();
Node nextToAppend;
do {
nextToAppend = range.nextSibling();
// If nextToAppend is null, something is really wrong...
// Commented out to let it crash and investigate,
// so far it did not happen.
//if (nextToAppend == null)
// break;
range.appendChild(nextToAppend);
} while (nextToAppend != endEl);
return range;
}
/**
* Wrap the supplied HTML around the "range" from startEl to endEl.*
* #param startEl the first element to be included into the range
* #param stOffset if startEl is TextNode, split at this offset
* and include only the tail. Otherwise ignored.
* #param endEl the last element to be included into the range
* #param endOffset if endEl is a Text node, split at this offset
* and include only the head. Otherwise ignored.
* #param html HTML to wrap around this element, e.g. {#code <span class="head"></span>}. Can be arbitrarily deep.
* #return the wrapping element
*/
public static Element wrapRange(Node startEl, int stOffset, Node endEl, int endOffset, String html) {
if (stOffset > 0 && startEl instanceof TextNode) {
TextNode tn = (TextNode) startEl;
if (endOffset < tn.getWholeText().length()-1) {
startEl = tn.splitText(stOffset); // Splits tn and adds tail to DOM, returns tail
}
}
if (endOffset > 0 && endEl instanceof TextNode) {
TextNode tn = (TextNode) endEl;
if (endOffset < tn.getWholeText().length()-1) {
tn.splitText(stOffset); // Splits tn and adds tail to DOM, we take head == original endEl
}
}
return wrapRange(startEl, endEl, html);
}
/**
* Calculate the depth of the range between the two given nodes, relative to body.
* The body has depth 0.
* #param startNode the first element to be included into the range
* #param endNode the last element to be included into the range
* #return minimum depth found in the range
*/
public static int getRangeMinDepth(final Node startNode, final Node endNode) {
class DepthVisitor implements NodeWalker.NodeWalkVisitor {
private int _minDepth = Integer.MAX_VALUE;
public boolean head(Node node, int depth) {
if (depth < _minDepth)
_minDepth = depth;
return true;
}
public boolean tail(Node node, int depth) {return true;}
int getMinDepth() { return _minDepth; }
};
DepthVisitor visitor = new DepthVisitor();
NodeWalker nw = new NodeWalker(visitor);
nw.walk(startNode, endNode);
return visitor.getMinDepth();
}
}
...and the NodeWalker.java the above code uses, adapted from NodeTraversor and NodeVisitor classes in jsoup package:
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.NodeVisitor;
/**
* Depth-first node traversor. Use to iterate through all nodes under and including the specified root node.
* <p>
* This implementation does not use recursion, so a deep DOM does not risk blowing the stack.
* </p>
*/
public class NodeWalker {
private NodeWalkVisitor visitor;
/**
* Create a new traversor.
* #param visitor a class implementing the {#link NodeVisitor} interface, to be called when visiting each node.
*/
public NodeWalker(NodeWalkVisitor visitor) {
this.visitor = visitor;
}
/**
* Start a depth-first traverse of the whole body and all of its descendants.
* #param startNode the arbitrary start point node point within body to traverse from.
* #param endNode the arbitrary end point node point within body where we stop traverse.
* Can be null, in which case we walk until the end of the body.
*/
public void walk(Node startNode, Node endNode) {
Node node = startNode;
int depth = getNodeDepth(startNode); // let's calulate depth relative to body, body is depth 0
while (node != null) {
if (!visitor.head(node, depth))
break;
if (node.childNodeSize() > 0) {
node = node.childNode(0);
depth++;
} else {
while (node.nextSibling() == null && depth > 0) {
if (!visitor.tail(node, depth) || node == endNode)
return;
node = node.parentNode();
depth--;
}
if (!visitor.tail(node, depth) || node == endNode)
break;
node = node.nextSibling();
}
}
}
// The walkBack() was not needed, but leaving it here, may be useful for something...
// /**
// * Start a depth-first backward traverse of the whole body and all of its descendants.
// * #param startNode the arbitrary start point node point within body to traverse from.
// * #param endNode the arbitrary end point node point within body where we stop traverse.
// * Can be null, in which case we walk until the end of the body.
// */
// public void walkBack(Node startNode, Node endNode) {
// Node node = startNode;
// int depth = getNodeDepth(startNode); // let's calulate depth relative to body, body is depth 0
//
// while (node != null) {
// if (!visitor.tail(node, depth))
// break;
// if (node.childNodeSize() > 0) {
// node = node.childNode(node.childNodeSize() - 1);
// depth++;
// } else {
// while (node.previousSibling() == null && depth > 0) {
// if (!visitor.head(node, depth) || node == endNode)
// return;
// node = node.parentNode();
// depth--;
// }
// if (!visitor.head(node, depth) || node == endNode)
// break;
// node = node.previousSibling();
// }
// }
// }
/**
* Calculate the depth of the given node relative to body. The body has depth 0.
* #param givenNode the node within the body to calculate depth for.
* #return the depth of the givenNode
*/
public static int getNodeDepth(Node givenNode) {
Node node = givenNode;
int depth = 0; // let's calulate depth relative to body, body is depth 0
if (!(node instanceof Element) || !"body".equals(((Element) node).tagName())) {
do {
depth++;
node = (Element)node.parentNode();
} while (node != null && !"body".equals(((Element) node).tagName()));
}
return depth;
}
public interface NodeWalkVisitor {
/**
* Callback for when a node is first visited.
*
* #param node the node being visited.
* #param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node
* of that will have depth 1.
* #return true to continue walk, false to abort
*/
boolean head(Node node, int depth);
/**
* Callback for when a node is last visited, after all of its descendants have been visited.
*
* #param node the node being visited.
* #param depth the depth of the node, relative to the root node. E.g., the root node has depth 0, and a child node
* of that will have depth 1.
* #return true to continue walk, false to abort
*/
boolean tail(Node node, int depth);
}
}
Greg

How do I add polyline length to a Bing Maps polygon

I am trying to recreate a tax map within my system using Bing Maps. My problem is in listing the length, in feet, of the sides of the polygons I am creating. I have a good idea of how to get the length of polylines I am creating from the MSSQL 2012 geometry or geography items in my database. I cannot figure out how to present it to the user effectively though. I have two ideas for how I would like to do this.
Place the lengths directly on or adjacent to the polyline in question.
Create an emphasized point on the full polygon and list to the side of the map, the lengths of the sides of the polygon based on a clockwise order.
Either of the 2 options would work as an acceptable solution. I used this tutorial to create my current environment so I would be looking to integrate the solution into it in some way:
How to create a spatial web service that connects a database to Bing Maps using EF5
Note that my implementation only uses the countries part of the code so I do not need to deal with single points like cities that are in that tutorial.
The relevant piece of code that handles drawing on the map that I would need to edit can be found here:
Bing Maps v7 WellKnowTextModule
If you want to get the perimeter of a polygon in SQL2012 you can grab the exterior ring of it. The exterior ring will be a LineString i.e. "#g.STExteriorRing()". Then measure the length along that line. i.e. "#g.STExteriorRing().STLength()". However, countries are usually not just single Polygons, they can be MultiPpolygons, or GeometryCollections. So to calculate these lengths we have to do a bit more work. Here is a helper method you can add to the service to calculate the perimeters of these shapes:
private double CalculateLength(SqlGeometry geom)
{
double length = 0;
if(string.Compare(geom.STGeometryType().Value, "polygon", true) == 0)
{
}
else if (string.Compare(geom.STGeometryType().Value, "multipolygon", true) == 0)
{
int numPolygon = geom.STNumGeometries().Value;
for(int i = 1; i <= numPolygon; i++){
length += geom.STGeometryN(i).STExteriorRing().STLength().Value;
}
}
else if (string.Compare(geom.STGeometryType().Value, "geometrycollection", true) == 0)
{
int numGeom = geom.STNumGeometries().Value;
for (int i = 1; i <= numGeom; i++)
{
length += CalculateLength(geom.STGeometryN(i));
}
}
return length;
}
To get the length info from the server side to the client add a property to the Country or BaseEntity class like this:
[DataMember]
public double Perimeter { get; set; }
From here you can populate this value after the linq query is used to get the response results using a simple loop that calls the helper method from earlier:
for (int i = 0; i < r.Results.Count;i++)
{
var geom = SqlGeometry.STGeomFromText(new System.Data.SqlTypes.SqlChars(r.Results[i].WKT), 4326);
r.Results[i].Perimeter = CalculateLength(geom);
}
As for displaying the information on the map. An easy way to place the information on a polyline is to choose a coordinate along the line, perhaps the middle one, just get the # or coordinates in the line and find the middle index and use that coordinate for a pushpin. You can then create a custom push using either a background image with text, or using custom HTML:
http://www.bingmapsportal.com/ISDK/AjaxV7#Pushpins4
http://www.bingmapsportal.com/ISDK/AjaxV7#Pushpins15
Wanted to add an addendum to the answer I accepted as I feel it changes it a bit.
While working on this I found that I was not actually able to get each line segment's length via entity framework. This is due to the fact that the query required changing the geography I had back to a geometry then parse it to its base line segments and then change those line segments back to geographies. The query, even in SQL, would take minutes so it was not an option to run dynamically in EF.
I ended up creating another table in my database containing the parsed line segments for each side of each polygon I had. Then I could use the centroids of the line segments as faux cities. I then added this logic into the DisplayData javascript function from the tutorial mentioned in the question after the for loop in the method.
if (shape.getLength) {
} else {
var chkPolygon = data.Results[0].WKT.substring(0, data.Results[0].WKT.indexOf('(', 0));
chkPolygon = chkPolygon.replace(/\s/g, '');
switch (chkPolygon.toLowerCase()) {
case 'point':
case 'polygon':
var latlonCheck = map.getCenter();
var setSides = window.location.origin + "/SpatialService.svc/FindNearBy?latitude=" +
latlonCheck.latitude + "&longitude=" + latlonCheck.longitude +
"&radius=" + data.Results[0].ID + "&layerName=" + "city" + "&callback=?";
CallRESTService(setSides, DisplaySides);
default:
break;
}
}
the data.Results[0].ID would find all the line segments in the new table for that specific country. Then the DisplaySides function is used to overlay the html pushpins as "cities" over the appropriate points for each side on the map
function DisplaySides(getSides) {
infobox.setOptions({ visible: false });
if (getSides && getSides.Results != null) {
for (var i = 0; i < getSides.Results.length; i++) {
var sideLenFtShort = Math.round(getSides.Results[i].LengthFeet * 100) / 100;
var htmlLenString = "<div style='font-size:14px;border:thin solid black;background-color:white;font-weight:bold;color:black;'>" + sideLenFtShort.toString(); + "</div>";
var testString = {
pushpinOptions: { width: null, height: null, htmlContent: htmlLenString }
};
var sideCtr = WKTModule.Read(getSides.Results[i].WKT, testString);
dataLayer.push(sideCtr);
}
}
else if (getSides && getSides.Error != null) {
alert("Error: " + getSides.Error);
}
}