1 votos

Leaftletjs punto animado o estático que parece ola

Basado en la buena explicación en este post Leaftletjs carga XML y GeoJSON Me las arreglé para conseguir puntos de terremoto que funciona bien. Ahora mi idea era en lugar de círculo para utilizar SVG o PNG marcador para mostrar la onda del terremoto.

Algo así

enter image description here

En la página de Leaflet encontré el siguiente código y ajustado también creó circle.png.

var LeafIcon = L.Icon.extend({
    options: {
        iconSize:     [200, 200],
        iconAnchor:   [100, 100],
    }
});
var greenIcon = new LeafIcon({iconUrl: 'circle.png'});
L.marker([45.6524,15.4909], {icon: greenIcon}).addTo(map);

Esto también está bien, pero ¿cómo puedo utilizar el código anterior en el código de abajo y cambiar el tamaño del icono basado en la magnitud del terremoto y establecer el centro donde está el terremoto?

 pointToLayer: function (feature, latlng) {
        var color,
            mag,
            radius,
            weight;
            mag = feature.properties.mag;
        if (mag === null) {
            color = '#FF0000';
            radius = 2;
            weight = 0.9;
        } else {
            color = '#FF0000';
            radius = 2 * Math.max(mag, 1);
            weight = 0.9;
        }
        if (feature.properties.type === 'quarry blast') {
            color = '#FF00FF';
        }
        return L.circleMarker(latlng, {
            color: color,
            radius: radius,
            weight: weight
        });
    }

3voto

IvanSanchez Puntos 491

Voy a adoptar un enfoque basado en Folleto.GLMarkers adaptado de algunas de sus demostraciones con símbolos dependientes del tiempo.

Se trataría del siguiente sombreador de vértices:

attribute vec2 aCRSCoords;
attribute vec2 aExtrudeCoords;
uniform mat4 uTransformMatrix;
uniform vec2 uPixelSize;
varying vec2 vPixel;

void main(void) {
    // Copy the input extrude coords to the varying
    vPixel = aExtrudeCoords * 30.0;

    gl_Position =
        uTransformMatrix * vec4(aCRSCoords, 1.0, 1.0) +
        vec4(aExtrudeCoords * uPixelSize * 80.0, 0.0, 0.0);
}

...y el siguiente fragment shader:

precision highp float;
varying vec2 vPixel;
uniform float uNow;

void main(void) {
    float radiusSquared = vPixel.x * vPixel.x + vPixel.y * vPixel.y;
    float hue = pow(radiusSquared, 1.2) / (800.0);

    hue -= uNow / 2000.0;
    hue = fract(hue);
    vec3 colour = vec3(1., 0., 0.);

    float alpha = smoothstep(30.0*30.0, 28.0*28.0, radiusSquared);
    alpha *= min(
        smoothstep(0.57, 0.65, hue),
        1. - smoothstep(0.92, 1., hue)
     );

    gl_FragColor = vec4(colour, alpha);
}

Esto incluye un cierto antialiasing básico de las ondas (el smoothstep s), y la opacidad de los píxeles depende del radio a la potencia de 2,4 más el tiempo, construyendo el efecto deseado (o algo muy cercano al efecto deseado).

animation of result

Se trata de una aplicación de libro de texto de un campo de distancia con signo 2D. Al final, las matemáticas se reducen a crear una función matemática que tiene el radio y el tiempo como entrada, y la opacidad como salida. En lo que respecta a shaders 2D y SDFs, siempre puedo recomendar la lectura de https://thebookofshaders.com/ (lea también la documentación y los ejemplos de GLMarkers).

El ejemplo anterior puede probarse en directo en https://ivansanchez.gitlab.io/Leaflet.GLMarkers/demo/repl.html - sustituir el código del sombreador de vértices y fragmentos según sea necesario. Ten en cuenta que los atributos por marcador pueden utilizarse como variables dentro de los shaders (por ejemplo, para controlar la distancia de extrusión, o los umbrales de opacidad, o la velocidad), como demuestran otros ejemplos en ese mismo REPL.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X