nachdem ich vorhin mal wieder auf des Netzwolfens Internetseite gestöbert habe, bin ich auf folgendes Codebeispiel gestoßen.
var messpunkte;
map.addLayer (messpunkte = new OpenLayers.Layer.Vector('Messpunkte', {
projection: new OpenLayers.Projection('EPSG:4326'),
//--------------------------------------------------------------------
// Darstellung der POIs:
//--------------------------------------------------------------------
styleMap: new OpenLayers.StyleMap ({
'default': new OpenLayers.Style ({
pointRadius: 10,
strokeColor: '${getColor}',
strokeWidth: 1,
strokeOpacity: 0.8,
fillColor: '${getColor}',
fillOpacity: 0.5
},{
context: {
getColor: function(feature) {
var ele = parseFloat(feature.attributes.ele);
if (isNaN(ele)) return 'black';
var minEle = 36;
var maxEle = 508;
var factor = (ele-minEle) / (maxEle-minEle);
if (factor<0 || factor>1) return 'black';
// rainbow ... (at least kind of)
var red = Math.round (255 * Math.max(2*factor-1,0));
var green= Math.round (255 * Math.min(2*factor,2-2*factor));
var blue = Math.round (255 * Math.max(1-2*factor,0));
// create hex color string
var value = (red << 16) | (green << 8) | blue;
var hexcolor = ((1<<24)|value).toString(16).substring(1);
return '#' + hexcolor;
}
}
}),
'select': new OpenLayers.Style ({
pointRadius: 10,
strokeColor: 'black',
strokeWidth: 3,
strokeOpacity: 1.0,
fillColor: 'white',
fillOpacity: 0.5,
label: '${ele}m',
labelYOffset: 30,
labelAlign: 'ct',
})
}),
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: 'elevations.csv',
format: new OpenLayers.Format.Text({extractStyles: false})
})
}));
Meine Frage an dieser Stelle wäre: Wie kann man nun den Radius des Features ebenfalls abhängig von dem Wert aus der CSV anpassen, mal angenommen, der Radius stünde in der CSV?
Prima wäre natürlich, wenn der Radius in Metern dann auch dem auf der Karte entspräche, also je dichter der Zoom desto größer der Kreis.
In meiner Wühlkiste finde ich nur dieses Beispiel (für Geduldige, dauert bisschen, bis was kommt…). Das Skaliert allerdings nicht mit einem angegebenen Radius, da wird nur ein png-Icon ein bisschen aufgeblasen. Deshalb ist der Rand auch ein wenig zackig bei grossen Kreisen, aber das kann man vielleicht auch hübscher hinbekommen. Die gewünschte Größe des Icons ist in der vorletzten Spalte der Textdatei, die letzte Spalte ist immer die Hälfte der Größe, damit der Kreis zentriert wird.
Skalieren mit der Zoomstufe kann es nicht. Falls ich das wollte, würde ich statt einer CSV-Datei eine KML-Datei oder GeoJson erstellen und die dann darstellen.
context: {
getRadius: function(feature) {
var radius = parseFloat(feature.attributes.radius); //oder wie immer der radius auch heißt -> debugger anwerfen
return (radius);
},
getColor: function(feature) {
function circle (llat, llon, icolor, ifill, radius) {
var polygonFeature = [];
var point = setToMercator(llon,llat); // alert (point );
var center = new OpenLayers.Geometry.Point(point[0], point[1]); // alert (center);
var style_var = {
strokeColor : icolor, strokeOpacity: 0.5,
strokeWidth : 2, pointRadius : 6,
fill : ifill > 0, fillColor : icolor,
fillOpacity : ifill, pointerEvents: "visiblePainted" };
var pointList = [];
var rradius = radius /(Math.cos(3.14159* llat/180));
var npoin=32;
for (var k = 0; k < npoin; k++ ) {
pointList.push( new OpenLayers.Geometry.Point(center.x + Math.cos(2.0*3.14159/npoin * k)* rradius, center.y + Math.sin(2.0*3.14159/npoin * k)* rradius ) );
}
pointList.push( new OpenLayers.Geometry.Point(center.x + rradius, center.y ) );
if ( ifill > 0 ) { polygonFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LinearRing(pointList),null,style_var);
} else { polygonFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(pointList),null,style_var);
}
return ( polygonFeature );
}
function setToMercator(lon, lat) {
x = parseFloat(lon); y = parseFloat(lat);
var PI = 3.14159265358979323846;
x = x * 20037508.34 / 180;
y = Math.log (Math.tan ((90 + y) * PI / 360)) / (PI / 180);
y = y * 20037508.34 / 180;
return new Array(x,y);
}
Aufruf:
var circ1 = circle(lat,lon,"red",0.1,2000.0);
vectorLayer.addFeatures([circ1]);
map.addLayer(vectorLayer);
Auf der Karte erscheint ein Kreis, der mit der Karte skaliert .
Ein realer Kreis, sprich Abstand vom Mittelpunkt konstant, ist in unserer Gegend bei der Merkatorprojektion eine in Nord-Süd Richtung
gestreckte Elipse, deshalb ist der Radius auch nur ein Richtwert.
Um den Radius aus einer CSV oder gpx Datei zu holen, muss Du diese parsen und den Wert als Variable in die circle Funktion übergeben.