Files
MapLibreParticleLab/platform/android/MapLibreAndroid/src/cpp/native_map_view.hpp

447 lines
18 KiB
C++

#pragma once
#include <mln/map/change.hpp>
#include <mln/map/camera.hpp>
#include <mln/map/map.hpp>
#include <mln/util/noncopyable.hpp>
#include <mln/util/run_loop.hpp>
#include <mln/tile/tile_operation.hpp>
#include <mln/storage/network_status.hpp>
#include "annotation/marker.hpp"
#include "annotation/polygon.hpp"
#include "annotation/polyline.hpp"
#include "graphics/pointf.hpp"
#include "graphics/rectf.hpp"
#include "geojson/feature.hpp"
#include "geojson/geometry.hpp"
#include "gson/json_object.hpp"
#include "geometry/lat_lng.hpp"
#include "geometry/projected_meters.hpp"
#include "style/layers/layer_manager.hpp"
#include "style/sources/source.hpp"
#include "geometry/lat_lng_bounds.hpp"
#include "map/camera_position.hpp"
#include "map/image.hpp"
#include "style/light.hpp"
#include "native_map_options.hpp"
#include "bitmap.hpp"
#include <exception>
#include <string>
#include <jni.h>
#include <android/native_window.h>
#include <EGL/egl.h>
#include <jni/jni.hpp>
namespace mln {
namespace android {
class AndroidRendererFrontend;
class FileSource;
class MapRenderer;
class RenderingStats;
class NativeMapView : public MapObserver {
public:
static constexpr auto Name() { return "org/maplibre/android/maps/NativeMapView"; };
static void registerNative(jni::JNIEnv&);
NativeMapView(jni::JNIEnv&,
const jni::Object<NativeMapView>&,
const jni::Object<FileSource>&,
const jni::Object<MapRenderer>&,
const jni::Object<NativeMapOptions>&);
virtual ~NativeMapView();
// mln::RendererBackend (mln::MapObserver) //
void onCameraWillChange(MapObserver::CameraChangeMode) override;
void onCameraIsChanging() override;
void onCameraDidChange(MapObserver::CameraChangeMode) override;
void onWillStartLoadingMap() override;
void onDidFinishLoadingMap() override;
void onDidFailLoadingMap(MapLoadError, const std::string&) override;
void onWillStartRenderingFrame() override;
void onDidFinishRenderingFrame(const MapObserver::RenderFrameStatus&) override;
void onWillStartRenderingMap() override;
void onDidFinishRenderingMap(MapObserver::RenderMode) override;
void onDidBecomeIdle() override;
void onDidFinishLoadingStyle() override;
void onSourceChanged(mln::style::Source&) override;
void onStyleImageMissing(const std::string&) override;
bool onCanRemoveUnusedStyleImage(const std::string&) override;
// JNI //
void resizeView(jni::JNIEnv&, int, int);
jni::Local<jni::String> getStyleUrl(jni::JNIEnv&);
void setStyleUrl(jni::JNIEnv&, const jni::String&);
jni::Local<jni::String> getStyleJson(jni::JNIEnv&);
void setStyleJson(jni::JNIEnv&, const jni::String&);
void setLatLngBounds(jni::JNIEnv&, const jni::Object<mln::android::LatLngBounds>&);
void cancelTransitions(jni::JNIEnv&);
void setGestureInProgress(jni::JNIEnv&, jni::jboolean);
void moveBy(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jlong);
void jumpTo(jni::JNIEnv&,
jni::jdouble,
jni::jdouble,
jni::jdouble,
jni::jdouble,
jni::jdouble,
const jni::Array<jni::jdouble>&);
void easeTo(jni::JNIEnv&,
jni::jdouble,
jni::jdouble,
jni::jdouble,
jni::jlong,
jni::jdouble,
jni::jdouble,
const jni::Array<jni::jdouble>&,
jni::jboolean);
void flyTo(jni::JNIEnv&,
jni::jdouble,
jni::jdouble,
jni::jdouble,
jni::jlong,
jni::jdouble,
jni::jdouble,
const jni::Array<jni::jdouble>&);
jni::Local<jni::Object<LatLng>> getLatLng(JNIEnv&);
void setLatLng(jni::JNIEnv&, jni::jdouble, jni::jdouble, const jni::Array<jni::jdouble>&, jni::jlong);
jni::Local<jni::Object<CameraPosition>> getCameraForLatLngBounds(jni::JNIEnv&,
const jni::Object<mln::android::LatLngBounds>&,
double top,
double left,
double bottom,
double right,
double bearing,
double tilt);
jni::Local<jni::Object<CameraPosition>> getCameraForGeometry(jni::JNIEnv&,
const jni::Object<geojson::Geometry>&,
double top,
double left,
double bottom,
double right,
double bearing,
double tilt);
void setReachability(jni::JNIEnv&, jni::jboolean);
void resetPosition(jni::JNIEnv&);
jni::jdouble getPitch(jni::JNIEnv&);
void setPitch(jni::JNIEnv&, jni::jdouble, jni::jlong);
void setZoom(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong);
jni::jdouble getZoom(jni::JNIEnv&);
void resetZoom(jni::JNIEnv&);
void setMinZoom(jni::JNIEnv&, jni::jdouble);
jni::jdouble getMinZoom(jni::JNIEnv&);
void setMaxZoom(jni::JNIEnv&, jni::jdouble);
jni::jdouble getMaxZoom(jni::JNIEnv&);
void setMinPitch(jni::JNIEnv&, jni::jdouble);
jni::jdouble getMinPitch(jni::JNIEnv&);
void setMaxPitch(jni::JNIEnv&, jni::jdouble);
jni::jdouble getMaxPitch(jni::JNIEnv&);
void rotateBy(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong);
void setBearing(jni::JNIEnv&, jni::jdouble, jni::jlong);
void setBearingXY(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jdouble, jni::jlong);
jni::jdouble getBearing(jni::JNIEnv&);
void resetNorth(jni::JNIEnv&);
void setVisibleCoordinateBounds(
JNIEnv&, const jni::Array<jni::Object<LatLng>>&, const jni::Object<RectF>&, jni::jdouble, jni::jlong);
void getVisibleCoordinateBounds(JNIEnv& env, jni::Array<jdouble>& output);
void scheduleSnapshot(jni::JNIEnv&);
jni::Local<jni::Object<CameraPosition>> getCameraPosition(jni::JNIEnv&);
void updateMarker(jni::JNIEnv&, jni::jlong, jni::jdouble, jni::jdouble, const jni::String&);
jni::Local<jni::Array<jni::jlong>> addMarkers(jni::JNIEnv&, const jni::Array<jni::Object<Marker>>&);
void onLowMemory(JNIEnv& env);
void setDebug(JNIEnv&, jni::jboolean);
jni::jboolean getDebug(JNIEnv&);
void setRetainedUnderlayEnabled(JNIEnv&, jni::jboolean);
jni::jboolean setContinuousLayerRange(JNIEnv&, const jni::String&, const jni::String&);
jni::jboolean setRenderSegmentPlan(JNIEnv&, const jni::String&);
jni::Local<jni::String> getRenderSegmentDiagnostics(JNIEnv&);
jni::Local<jni::Array<jni::String>> getRetainedUnderlayDiagnostics(JNIEnv&);
jni::Local<jni::Array<jni::String>> getActionJournalLogFiles(JNIEnv&);
jni::Local<jni::Array<jni::String>> getActionJournalLog(JNIEnv&);
void clearActionJournalLog(JNIEnv&);
jni::jboolean isFullyLoaded(JNIEnv&);
jni::jdouble getMetersPerPixelAtLatitude(JNIEnv&, jni::jdouble, jni::jdouble);
jni::Local<jni::Object<ProjectedMeters>> projectedMetersForLatLng(JNIEnv&, jni::jdouble, jni::jdouble);
jni::Local<jni::Object<PointF>> pixelForLatLng(JNIEnv&, jdouble, jdouble);
void pixelsForLatLngs(JNIEnv&, const jni::Array<jdouble>&, jni::Array<jdouble>&, jfloat);
jni::Local<jni::Object<LatLng>> latLngForProjectedMeters(JNIEnv&, jdouble, jdouble);
jni::Local<jni::Object<LatLng>> latLngForPixel(JNIEnv&, jfloat, jfloat);
void latLngsForPixels(JNIEnv&, const jni::Array<jdouble>&, jni::Array<jdouble>&, jfloat);
jni::Local<jni::Array<jlong>> addPolylines(JNIEnv&, const jni::Array<jni::Object<Polyline>>&);
jni::Local<jni::Array<jlong>> addPolygons(JNIEnv&, const jni::Array<jni::Object<Polygon>>&);
void updatePolyline(JNIEnv&, jlong, const jni::Object<Polyline>&);
void updatePolygon(JNIEnv&, jlong, const jni::Object<Polygon>&);
void removeAnnotations(JNIEnv&, const jni::Array<jlong>&);
void addAnnotationIcon(JNIEnv&, const jni::String&, jint, jint, jfloat, const jni::Array<jbyte>&);
void removeAnnotationIcon(JNIEnv&, const jni::String&);
jni::jdouble getTopOffsetPixelsForAnnotationSymbol(JNIEnv&, const jni::String&);
jni::Local<jni::Object<TransitionOptions>> getTransitionOptions(JNIEnv&);
void setTransitionOptions(JNIEnv&, const jni::Object<TransitionOptions>&);
jni::Local<jni::Array<jlong>> queryPointAnnotations(JNIEnv&, const jni::Object<RectF>&);
jni::Local<jni::Array<jlong>> queryShapeAnnotations(JNIEnv&, const jni::Object<RectF>&);
jni::Local<jni::Array<jni::Object<geojson::Feature>>> queryRenderedFeaturesForPoint(
JNIEnv&, jni::jfloat, jni::jfloat, const jni::Array<jni::String>&, const jni::Array<jni::Object<>>& jfilter);
jni::Local<jni::Array<jni::Object<geojson::Feature>>> queryRenderedFeaturesForBox(
JNIEnv&,
jni::jfloat,
jni::jfloat,
jni::jfloat,
jni::jfloat,
const jni::Array<jni::String>&,
const jni::Array<jni::Object<>>& jfilter);
void setFeatureState(JNIEnv&,
const jni::String& sourceId,
const jni::String& sourceLayerId,
const jni::String& featureId,
const jni::Object<gson::JsonObject>& state);
jni::Local<jni::Object<gson::JsonObject>> getFeatureState(JNIEnv&,
const jni::String& sourceId,
const jni::String& sourceLayerId,
const jni::String& featureId);
void removeFeatureState(JNIEnv&,
const jni::String& sourceId,
const jni::String& sourceLayerId,
const jni::String& featureId,
const jni::String& stateKey);
jni::Local<jni::Object<Light>> getLight(JNIEnv&);
jni::Local<jni::Array<jni::Object<Layer>>> getLayers(JNIEnv&);
jni::Local<jni::Object<Layer>> getLayer(JNIEnv&, const jni::String&);
jni::jboolean hasStyleLayer(JNIEnv&, const jni::String&);
jni::jboolean setStyleLayerFloatProperty(JNIEnv&, const jni::String&, const jni::String&, jni::jfloat);
jni::jboolean setWeatherColorOpacity(JNIEnv&, const jni::String&, jni::jfloat);
jni::jboolean setStyleLayerVisibility(JNIEnv&, const jni::String&, jni::jboolean);
jni::jboolean setRasterParticleColors(JNIEnv&, const jni::String&, const jni::Array<jni::jfloat>&, const jni::Array<jni::jfloat>&);
jni::jboolean setRasterParticleColor(JNIEnv&, const jni::String&, const jni::Array<jni::jfloat>&);
jni::jboolean setRasterParticleTrailColor(JNIEnv&, const jni::String&, const jni::Array<jni::jfloat>&);
jni::jboolean setRasterArraySourceTargetFps(JNIEnv&, const jni::String&, jni::jint);
jni::jint getRasterArraySourceTargetFps(JNIEnv&, const jni::String&);
jni::jboolean setWeatherColorStops(JNIEnv&, const jni::String&, const jni::Array<jni::jfloat>&, const jni::Array<jni::jfloat>&);
jni::jint getWeatherColorStopCapacity(JNIEnv&);
jni::jboolean advanceRasterArraySourceFieldWindow(JNIEnv&, const jni::String&);
jni::jboolean repeatRasterArraySourceFieldWindow(JNIEnv&, const jni::String&);
jni::jint submitRasterArraySourceHostField(JNIEnv&,
const jni::String&,
const jni::String&,
const jni::Array<jbyte>&);
jni::jint submitRasterArraySourceHostFieldV2(JNIEnv&,
const jni::String&,
const jni::String&,
const jni::Array<jbyte>&,
jni::jboolean,
jni::jint,
jni::jboolean,
jni::jint,
jni::jint);
jni::jboolean clearRasterArraySourceHostFields(JNIEnv&, const jni::String&);
jni::jboolean resetRasterArraySourceWeatherRuntime(JNIEnv&, const jni::String&);
jni::jboolean seekRasterArraySourceTimelineToTimestamp(JNIEnv&, const jni::String&, jni::jlong);
jni::jboolean controlRasterArraySourceTimeline(JNIEnv&, const jni::String&, jni::jint, jni::jfloat);
jni::jint submitRasterArraySourceEncodedField(JNIEnv&, const jni::String&, const jni::String&, const jni::String&, jni::jlong, jni::jlong, const jni::String&, const jni::Array<jbyte>&);
jni::jint clearRasterArraySourceEncodedField(JNIEnv&, const jni::String&, const jni::String&);
jni::jint clearAllRasterArraySourceEncodedFields(JNIEnv&, const jni::String&);
jni::jint setRasterArraySourceEncodedColorBinding(JNIEnv&, const jni::String&, const jni::String&, jni::jint, jni::jint, jni::jint, jni::jint);
jni::jint setRasterArraySourceEncodedParticleBinding(JNIEnv&, const jni::String&, const jni::String&, jni::jint, jni::jint, jni::jint, jni::jint, jni::jint, jni::jint, jni::jint, jni::jint);
jni::jint setRasterArraySourceEncodedForecastTime(JNIEnv&, const jni::String&, jni::jlong);
jni::jint setRasterArraySourceEncodedForecastPlaybackState(JNIEnv&, const jni::String&, jni::jboolean);
jni::jint setRasterArraySourceEncodedForecastPlaybackSpeed(JNIEnv&, const jni::String&, jni::jfloat);
void addLayer(JNIEnv&, jlong, const jni::String&);
void addLayerAbove(JNIEnv&, jlong, const jni::String&);
void addLayerAt(JNIEnv&, jni::jlong, jni::jint);
jni::jboolean removeLayerAt(JNIEnv&, jni::jint);
jni::jboolean removeLayer(JNIEnv&, jlong);
jni::Local<jni::Array<jni::Object<Source>>> getSources(JNIEnv&);
jni::Local<jni::Object<Source>> getSource(JNIEnv&, const jni::String&);
jni::jboolean hasStyleSource(JNIEnv&, const jni::String&);
void addSource(JNIEnv&, const jni::Object<Source>&, jlong nativePtr);
jni::jboolean removeSource(JNIEnv&, const jni::Object<Source>&, jlong nativePtr);
void addImage(JNIEnv&, const jni::String&, const jni::Object<Bitmap>& bitmap, jni::jfloat, jni::jboolean);
void addImages(JNIEnv&, const jni::Array<jni::Object<mln::android::Image>>&);
void removeImage(JNIEnv&, const jni::String&);
jni::Local<jni::Object<Bitmap>> getImage(JNIEnv&, const jni::String&);
void setPrefetchTiles(JNIEnv&, jni::jboolean);
jni::jboolean getPrefetchTiles(JNIEnv&);
void setPrefetchZoomDelta(JNIEnv&, jni::jint);
jni::jint getPrefetchZoomDelta(JNIEnv&);
void setTileCacheEnabled(JNIEnv&, jni::jboolean);
jni::jboolean getTileCacheEnabled(JNIEnv&);
void setTileLodMinRadius(JNIEnv&, jni::jdouble);
jni::jdouble getTileLodMinRadius(JNIEnv&);
void setTileLodScale(JNIEnv&, jni::jdouble);
jni::jdouble getTileLodScale(JNIEnv&);
void setTileLodPitchThreshold(JNIEnv&, jni::jdouble);
jni::jdouble getTileLodPitchThreshold(JNIEnv&);
void setTileLodZoomShift(JNIEnv&, jni::jdouble);
jni::jdouble getTileLodZoomShift(JNIEnv&);
mln::Map& getMap();
void triggerRepaint(JNIEnv&);
jni::jboolean isRenderingStatsViewEnabled(JNIEnv&);
void enableRenderingStatsView(JNIEnv&, jni::jboolean);
void setFrustumOffset(JNIEnv&, const jni::Object<RectF>&);
// Shader compilation
void onRegisterShaders(mln::gfx::ShaderRegistry&) override;
void onPreCompileShader(mln::shaders::BuiltIn, mln::gfx::Backend::Type, const std::string&) override;
void onPostCompileShader(mln::shaders::BuiltIn, mln::gfx::Backend::Type, const std::string&) override;
void onShaderCompileFailed(mln::shaders::BuiltIn, mln::gfx::Backend::Type, const std::string&) override;
// Glyph requests
void onGlyphsLoaded(const mln::FontStack&, const mln::GlyphRange&) override;
void onGlyphsError(const mln::FontStack&, const mln::GlyphRange&, std::exception_ptr) override;
void onGlyphsRequested(const mln::FontStack&, const mln::GlyphRange&) override;
// Tile requests
void onTileAction(mln::TileOperation, const mln::OverscaledTileID&, const std::string&) override;
// Sprite requests
void onSpriteLoaded(const std::optional<mln::style::Sprite>&) override;
void onSpriteError(const std::optional<mln::style::Sprite>&, std::exception_ptr) override;
void onSpriteRequested(const std::optional<mln::style::Sprite>&) override;
// Renderer
void onRenderError(std::exception_ptr) override;
void onSymbolError(const std::string&) override;
private:
std::shared_ptr<AndroidRendererFrontend> rendererFrontend;
JavaVM* vm = nullptr;
jni::WeakReference<jni::Object<NativeMapView>> javaPeer;
MapRenderer& mapRenderer;
std::string styleUrl;
float pixelRatio;
jni::Global<jni::Object<RenderingStats>> renderingStats;
// Minimum texture size according to OpenGL ES 2.0 specification.
int width = 64;
int height = 64;
static constexpr auto annotationRequestTimeout = std::chrono::milliseconds(200);
// Ensure these are initialised last
std::unique_ptr<mln::Map> map;
};
} // namespace android
} // namespace mln