ERROR TypeError: Cannot read property 'Point' of undefined, openlayers 3 & jsts - server-side - angularjs

I am attempting to follow this example in order to buffer some features drawn on the map.
However, that gives me the following error:
ERROR TypeError: Cannot read property 'Point' of undefined
Here is my code:
BufferFeature(feature){
var parser = new jsts.io.OL3Parser();
let format = new ol.format.WKT();
// convert the OpenLayers geometry to a JSTS geometry
var jstsGeom = parser.read(format.writeGeometry(feature.getGeometry()));
// create a buffer of 40 meters around each line
var buffered = jstsGeom.buffer(40);
// convert back from JSTS and replace the geometry on the feature
feature.setGeometry(parser.write(buffered));
let source = this.VectorOverlay.getSource();
source.addFeatures(feature);
}
Can someone identify where I am going wrong?

I finally solve this problem using the inject method of OL3Parse. your code should look like:
var Geojson = require('ol/format/geojson');
var Vector = require('ol/source/vector');
var Feature = require('ol/feature');
var LineString = require('ol/geom/linestring');
var Point = require('ol/geom/point');
var jsts = require('jsts');
var ol3Parser = new jsts.io.OL3Parser();
ol3Parser.inject(Point, LineString);
BufferFeature(feature){
let format = new ol.format.WKT();
// convert the OpenLayers geometry to a JSTS geometry
var jstsGeom = ol3Parser.read(format.writeGeometry(feature.getGeometry()));
// create a buffer of 40 meters around each line
var buffered = jstsGeom.buffer(40);
// convert back from JSTS and replace the geometry on the feature
feature.setGeometry(parser.write(buffered));
let source = this.VectorOverlay.getSource();
source.addFeatures(feature);
}
This works for:
function inject(Point, LineString, LinearRing, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection) {};

Related

How to convert hashSet<String> to arrayListOf?

Using shared preferences to save an arrayListOf in my app. Im converting the array to a hashset and saving it but when I load it I am unable to convert it back to an arrayListOf. I have tried toTypedArray() and toArray() but neither solve the problem. Getting the error below.
Required:
kotlin.collections.ArrayList /* = java.util.ArrayList */
Found:
(Mutable)Set<String!>?
Using the following to try and load the hashet and convert it.
var sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE)
var places = arrayListOf<String>()
var loadSet = sharedPreferences.getStringSet("key", null)
places = loadSet
go.setOnClickListener{
thread {
val place = newLocation.text.toString()
var stringCounter = counter.toString()
if(place !in places){
places.add(place)
//editor.putStringSet("key", places)
//editor.commit()
var sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE)
var editor = sharedPreferences.edit()
set.add(place)
editor.putStringSet("key", set);
editor.commit();
Log.d("set", set.toString())
var loadSet = sharedPreferences.getStringSet("key", HashSet<String>())?.toList()
Log.d("load", loadSet.toString())
places = loadSet as ArrayList<String>
}
arrayListOf isn’t a type. It’s a function. The type is ArrayList, but it’s more typical to only need the more abstract List or MutableList, depending on what you’re doing with it. For those you can use set.toList() or set.toMutableList().
If you have an existing ArrayList or MutableList, you could also do list.addAll(set).

Iterate over ee.FeatureCollection to compute regional statistics of an ee.ImageCollection

Dear Earth Engine community,
Can someone help me solving the following problem:
I want to compute the aggregate nightlight intensities (sum) within all first level administrative regions of the world. For that purpose I use a shapefile which contains the regional boundaries (GADM) and raster data on nightlight (VIIRS).
The issue with the following code is that 1) I am getting an error that say "Unknown element type provided: object. Expected: ee.Image, ee.ImageCollection, ee.FeatureCollection or ee.Element." for the nighttime.reduceRegion operation and 2) that only the last feature of the selection is returned on print(final).
Unfortunately I do not manage to solve these problems. It would be great if someone could help me improving the code. I am sure there are many issues since Javascript and the Earth Engine API are completely new to me..
Thanks a lot in advance!
// Import nighttime raster data.
var nighttimeCollection = ee.ImageCollection('NOAA/VIIRS/DNB/MONTHLY_V1/VCMSLCFG');
// Import shapefile containing region boundaries.
var region_boundaries = ee.FeatureCollection("users/hendrikscheewel/gadm_level_1");
// Select a specific year ::: Later this should be done within a loop.
var year = "2014";
// Aggregate monthly nighttime data to year x.
var nighttime = nighttimeCollection
.filter(ee.Filter.date(year+'-01-01', year+'-12-31'))
.select('avg_rad')
.reduce(ee.Reducer.mean());
// This function does the following:
// * Aggregrate nightlight data within a shape/feature by taking its sum,
// * Assign the result to the feature,
// * Create copy of feature with simplified geometry (centroid) and fewer columns,
// * Return the copy.
var compute_nightlight = function(feature) {
// Compute mean of average radiance for feature shape
var result = nighttime.reduceRegion({
geometry: feature.geometry(),
reducer: ee.Reducer.sum(),
scale: 30,
maxPixels: 1e9,
});
// Set "nightlight" as a new property.
feature = ee.Feature(feature.set('nightlight',result.get('avg_rad_mean')));
// Get the centroid of the feature's geometry.
var featureSimplified = feature.centroid();
// Keep this list of properties.
var keepProperties = ['GID_0','GID_1','NAME_0','NAME_1','nightlight'];
featureSimplified = featureSimplified.copyProperties(feature, keepProperties);
// Return a new Feature, copying properties from the old Feature.
return featureSimplified;
};
//print(compute_nightlight(region_boundaries.first()));
var final = region_boundaries.filter(ee.Filter.eq('NAME_0','Belgium')).iterate(compute_nightlight);
print(final)
Export.table.toDrive({
collection: final,
description: 'nl_'+year,
fileFormat: 'CSV'
});
Ok, I found my main mistake: Instead of using the .iterate() method I should have used the .map() method.
After some cleaning the code looks like this:
// Select a specific year
var year = "2014";
// Aggregate monthly nighttime data to year x.
var nighttime = nighttimeCollection
.filter(ee.Filter.date(year+'-01-01', year+'-12-31'))
.select('avg_rad')
.reduce(ee.Reducer.mean());
// This function does the following:
// * Aggregrate nightlight data within a shape/feature by taking its sum,
// * Assign the result to the feature,
// * Create copy of feature with simplified geometry (centroid) and fewer columns,
// * Return the copy.
var compute_nightlight = function(feature) {
// Compute mean of average radiance for feature shape
var result = nighttime.reduceRegion({
geometry: feature.geometry(),
reducer: ee.Reducer.sum(),
scale: 30,
maxPixels: 1e9,
});
// Set "nightlight" as a new property.
feature = ee.Feature(feature.set('nightlight',result.get('avg_rad_mean')));
// Return a new Feature, copying properties from the old Feature.
return feature.centroid();
};
var final = ee.FeatureCollection((region_boundaries).map(compute_nightlight));
Export.table.toDrive({
collection: final,
description: 'nl_'+year,
fileFormat: 'CSV'
});

Swift - Create circle and add to array

I've been looking for a little while on how to create a circle in Swift, but it seems quite complicated. I want to create a circle at run time, with a specified x and y, and width and height. I then want to add this circle to an array where I can create more circles and add to it.
How do I do this?
Edit: This is what I've tried so far:
var center : CGPoint = touchLocation
var myContext : CGContextRef = UIGraphicsGetCurrentContext()
let color : [CGFloat] = [0, 0, 1, 0.5]
CGContextSetStrokeColor (myContext, color);
CGContextStrokeEllipseInRect (myContext, CGRectMake(touchLocation.x, touchLocation.y, 20, 20));
touchLocation is the location of the users finger. This crashes on execution on this line:
var myContext : CGContextRef = UIGraphicsGetCurrentContext()
The error says "Unexpectedly found nil while unwrapping an Optional value
Also, this doesn't allow me to add the circle to an array, because I don't know what variable type it is.
There are many ways to draw a circle, here is a snippet that I have been hacking with:
func circleWithCenter(c:CGPoint, radius r:CGFloat,
strokeColor sc: UIColor = UIColor.blackColor(),
fillColor fc: UIColor = UIColor.clearColor()) -> CAShapeLayer {
var circle = CAShapeLayer()
circle.frame = CGRect(center:c, size:CGSize(width:2*r, height:2*r))
circle.path = UIBezierPath(ovalInRect:circle.bounds).CGPath
circle.fillColor = fc.CGColor
circle.strokeColor = sc.CGColor
circle.fillColor = fc == UIColor.clearColor() ? nil : fc.CGColor
return circle
}
Note that I extended CGRect (using Swift specific features) to add a initializer that takes a center, but that is not material to your question.
Your code is not "creating" a circle as an object, it is attempting to draw one in the graphics context. What you need to do is to create a bezier path object, draw into that and save the path in your array. Something like:
var circleArray = [CGMutablePathRef]()
// ...
let path: CGMutablePathRef = CGPathCreateMutable()
CGPathAddArc(path, nil, touchLocation.x, touchLocation.y, radius, 0, M_PI * 2, true)
circleArray += [path]
You then need to stroke the path(s) in your draw routine.

image array and .src - image not changing

I have created an array which is being used to store a series of .gif images and I'm just trying to test everything out by using document.getElementById to change the .src value but when I change it and load the page the image stays the same as it was before.
function setImage()
{
var images = new Array();
images[0] = anemone.gif;
images[1] = ball.gif;
images[2] = crab.gif;
images[3] = fish2.gif;
images[4] = gull.gif;
images[5] = jellyfish.gif;
images[6] = moon.gif;
images[7] = sail.gif;
images[8] = shell.gif;
images[9] = snail.gif;
images[10] = sun.gif;
images[11] = sunnies.gif;
images[12] = whale.gif;
var slots = new Array();
slots[0] = document.getElementById("slot" + 0);
slots[1] = document.getElementById("slot" + 1);
slots[2] = document.getElementById("slot" + 2);
slots[0].src = "snail.gif";
document.getElementById('slot0').src = images[0];
alert(images.length);
}
I can't understand why the image wont change, but I know it has to be something very simple. I've been wasting hours trying to get this one thing to change but nothing works. can anyone please point out the error of my ways?
There are a couple of issues with your code:
Your filenames need to be Strings, so they'll have to be quoted (also you can simplify the Array creation):
var images = ['anemone.gif', 'ball.gif', 'crab.gif', 'fish2.gif', 'gull.gif', 'jellyfish.gif', 'moon.gif', 'sail.gif', 'shell.gif', 'snail.gif', 'sun.gif', 'sunnies.gif', 'whale.gif'];
Also make sure you are getting your slot-elements right, quote all the attributes like:
<img id="slot0" class="slot" src="crab.gif" width="120" height="80">
When you create the slots-Array you can do it like this (no need to concat the ID string):
var slots = [document.getElementById('slot0'), document.getElementById('slot1'), document.getElementById('slot2')];
Finally make sure you call your function when the document has loaded / the DOM is ready. If you don't want to use a framework like jQuery your easiest bet is probably still using window.onload:
window.onload = setImage; //note that the parens are missing as you want to refer to the function instead of executing it
Further reading on Arrays, window.onload and DOMReady:
https://developer.mozilla.org/de/docs/DOM/window.onload
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array
javascript domready?

Amcharts SerialChart multiple line graphs different category value member paths (Silverlight)

EDIT I rewrote my question to make it more understandable after the conversation below with Tony (thanks!).
GOAL Render multiple line graphs (let's say 2) in the same chart. The charts have different x/y value pairs. For one x-value, I do not know both y-values.
I am using Silverlight. The classes available for this are SerialChart and LineGraph. The data source for both graphs is the same and is set at the SerialChart level. The name of the property for the x-axis is also defined there for both graphs (CategoryValueMemberPath).
As suggested by the amCharts documentation, we need to create objects that have a property for the category axis (x-axis) and then one property per graph. Let's call them "Graph1" and "Graph2". So the data source looks something like this:
List<MyClass> data = new List<MyClass>()
{
new MyClass() { Category = 0.1, Graph1 = 0.14, Graph2 = ??? }
,new MyClass() { Category = 0.15, Graph1 = ???, Graph2 = 0.05 }
,new MyClass() { Category = 0.2, Graph1 = 0.35, Graph2 = ??? }
,new MyClass() { Category = 0.18, Graph1 = ???, Graph2 = 0.12 }
... and so on ...
}
PROBLEM What am I supposed to do about the "???" values? I do not have the actual value for that graph for that category value.
If I do not set a value, the default value of 0.0 is assumed and it draws a spike to the x-axis. If I set the previously known Graph1/Graph2 value, then it creates a horizontal connection where there is not supposed to be one. I am basically altering the graph which leads to a wrong result.
So how do I solve this? I am getting the feeling that amCharts do not support this scenario.
You need to add two 'value' axes, one in the X direction and one in the Y direction (imagine, like a bubble chart).
// AXES
// X
var xAxis = new AmCharts.ValueAxis();
xAxis.position = "bottom";
xAxis.gridAlpha = 0.1;
xAxis.autoGridCount = true;
chart.addValueAxis(xAxis);
// Y
var yAxis = new AmCharts.ValueAxis();
yAxis.position = "left";
yAxis.gridAlpha = 0.1;
yAxis.autoGridCount = true;
chart.addValueAxis(yAxis);
Merge all your data points into one array with a common X axis field name ('x' in my example) and for points on line 1, add a property of 'line1' with its value, and for points on line 2, add a property of 'line2'.
For example, your data would look like this:
var chartData = [
{x:0.1,line1:0.25},
{x:0.246,line1:0.342},
{x:0.12,line2:0.16},
{x:0.3,line2:0.485}
];
Then add a 'graph' for each line to your chart specifying where to get the value from in the object array.
// GRAPHS
var graph = new AmCharts.AmGraph();
graph.xField = "x";
graph.yField = "line1";
graph.lineAlpha = 1;
graph.lineColor = '#FF9E01';
chart.addGraph(graph);
var graph2 = new AmCharts.AmGraph();
graph2.xField = "x";
graph2.yField = "line2";
graph.lineAlpha = 1;
graph2.lineColor = '#9EFF01';
chart.addGraph(graph2);
I've put all this into a Fiddle for you - http://jsfiddle.net/64EWx/

Resources