Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions CodenameOne/src/com/codename1/maps/CameraChangeListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Codename One in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.maps;

/// Receives camera movement notifications from a [MapSurface]. Register with
/// [MapSurface#addCameraChangeListener].
public interface CameraChangeListener {

/// Invoked on the EDT after the camera settles at a new position, whether
/// from a programmatic move or a user pan/zoom gesture.
///
/// #### Parameters
///
/// - `map`: the surface whose camera moved
///
/// - `position`: the new camera position
void cameraChanged(MapSurface map, CameraPosition position);
}
100 changes: 100 additions & 0 deletions CodenameOne/src/com/codename1/maps/CameraPosition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Codename One in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.maps;

/// An immutable description of the map camera: where it looks ([#getTarget]),
/// how far it is zoomed in ([#getZoom]), the compass bearing in degrees
/// ([#getBearing]) and the tilt away from nadir ([#getTilt]).
///
/// Zoom uses the standard slippy-map scale where each whole increment
/// doubles the scale (zoom 0 shows the whole world in a single 256px tile).
/// Fractional zoom is supported by the vector engine; native providers may
/// round it. Bearing and tilt are honored by native providers that support
/// them and ignored by the pure-vector [MapView].
public final class CameraPosition {

private final LatLng target;
private final double zoom;
private final double bearing;
private final double tilt;

/// Creates a camera position that looks straight down (no bearing/tilt).
public CameraPosition(LatLng target, double zoom) {
this(target, zoom, 0, 0);
}

/// Creates a fully specified camera position.
///
/// #### Parameters
///
/// - `target`: the geographic point at the center of the viewport
///
/// - `zoom`: the slippy-map zoom level
///
/// - `bearing`: the compass bearing in degrees (0 = north up)
///
/// - `tilt`: the viewing angle away from straight-down, in degrees
public CameraPosition(LatLng target, double zoom, double bearing, double tilt) {
this.target = target;
this.zoom = zoom;
this.bearing = bearing;
this.tilt = tilt;
}

/// The geographic point at the center of the viewport.
public LatLng getTarget() {
return target;
}

/// The slippy-map zoom level.
public double getZoom() {
return zoom;
}

/// The compass bearing in degrees (0 = north up).
public double getBearing() {
return bearing;
}

/// The viewing tilt in degrees (0 = straight down).
public double getTilt() {
return tilt;
}

/// Returns a copy of this position with a different target.
public CameraPosition withTarget(LatLng newTarget) {
return new CameraPosition(newTarget, zoom, bearing, tilt);
}

/// Returns a copy of this position with a different zoom level.
public CameraPosition withZoom(double newZoom) {
return new CameraPosition(target, newZoom, bearing, tilt);
}

/// {@inheritDoc}
@Override
public String toString() {
return "CameraPosition{target=" + target + ", zoom=" + zoom
+ ", bearing=" + bearing + ", tilt=" + tilt + "}";
}
}
113 changes: 113 additions & 0 deletions CodenameOne/src/com/codename1/maps/Circle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Codename One in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.maps;

/// A geodesic circle drawn on a map, described by a center and a radius in
/// meters. Add one through [MapSurface#addCircle(Circle)].
public final class Circle extends MapObject {

private LatLng center;
private double radiusMeters;
private int fillColor = 0x402196f3;
private int strokeColor = 0x2196f3;
private int strokeWidth = 2;
private boolean visible = true;

/// Creates a circle.
///
/// #### Parameters
///
/// - `center`: the geographic center
///
/// - `radiusMeters`: the radius in meters
public Circle(LatLng center, double radiusMeters) {
this.center = center;
this.radiusMeters = radiusMeters;
}

/// The circle center.
public LatLng getCenter() {
return center;
}

/// Moves the circle center.
public Circle setCenter(LatLng center) {
this.center = center;
return this;
}

/// The radius in meters.
public double getRadiusMeters() {
return radiusMeters;
}

/// Sets the radius in meters.
public Circle setRadiusMeters(double radiusMeters) {
this.radiusMeters = radiusMeters;
return this;
}

/// The fill color as 0xAARRGGBB (alpha in the high byte).
public int getFillColor() {
return fillColor;
}

/// Sets the fill color as 0xAARRGGBB (alpha in the high byte).
public Circle setFillColor(int fillColor) {
this.fillColor = fillColor;
return this;
}

/// The stroke color as 0xRRGGBB.
public int getStrokeColor() {
return strokeColor;
}

/// Sets the stroke color as 0xRRGGBB.
public Circle setStrokeColor(int strokeColor) {
this.strokeColor = strokeColor;
return this;
}

/// The stroke width in pixels (0 hides the outline).
public int getStrokeWidth() {
return strokeWidth;
}

/// Sets the stroke width in pixels (0 hides the outline).
public Circle setStrokeWidth(int strokeWidth) {
this.strokeWidth = strokeWidth;
return this;
}

/// Whether the circle is rendered.
public boolean isVisible() {
return visible;
}

/// Shows or hides the circle.
public Circle setVisible(boolean visible) {
this.visible = visible;
return this;
}
}
128 changes: 128 additions & 0 deletions CodenameOne/src/com/codename1/maps/LatLng.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright (c) 2026, Codename One and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Codename One designates this
* particular file as subject to the "Classpath" exception as provided
* by Codename One in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Codename One through http://www.codenameone.com/ if you
* need additional information or have any questions.
*/
package com.codename1.maps;

import com.codename1.util.MathUtil;

/// An immutable WGS84 geographic coordinate (latitude/longitude in degrees).
///
/// Unlike the legacy [Coord], `LatLng` is always unprojected (plain
/// lat/lon) and immutable, which makes it safe to share between the map
/// components, the vector engine and native providers. It is the value
/// type used throughout the modern maps API ([MapView], [NativeMap] and
/// [com.codename1.maps.spi.MapProvider]).
public final class LatLng {

private static final double EARTH_RADIUS_METERS = 6378137.0;
private static final double DELTA = 0.0000001;

private final double latitude;
private final double longitude;

/// Creates a coordinate from a latitude/longitude pair in degrees.
///
/// #### Parameters
///
/// - `latitude`: the latitude in degrees, clamped to the valid range
///
/// - `longitude`: the longitude in degrees, normalized to [-180, 180]
public LatLng(double latitude, double longitude) {
if (latitude > 90) {
latitude = 90;
} else if (latitude < -90) {
latitude = -90;
}
if (longitude > 180 || longitude < -180) {
longitude = ((longitude + 180) % 360 + 360) % 360 - 180;
}
this.latitude = latitude;
this.longitude = longitude;
}

/// Factory method mirroring the constructor for fluent call sites.
public static LatLng create(double latitude, double longitude) {
return new LatLng(latitude, longitude);
}

/// Converts a legacy [Coord] (assumed WGS84) into a `LatLng`.
public static LatLng fromCoord(Coord c) {
return new LatLng(c.getLatitude(), c.getLongitude());
}

/// The latitude in degrees in the range [-90, 90].
public double getLatitude() {
return latitude;
}

/// The longitude in degrees in the range [-180, 180].
public double getLongitude() {
return longitude;
}

/// Converts this coordinate into a legacy WGS84 [Coord].
public Coord toCoord() {
return new Coord(latitude, longitude, false);
}

/// The great-circle distance in meters between this coordinate and
/// `other`, computed with the haversine formula.
public double distanceTo(LatLng other) {
double dLat = Math.toRadians(other.latitude - latitude);
double dLon = Math.toRadians(other.longitude - longitude);
double lat1 = Math.toRadians(latitude);
double lat2 = Math.toRadians(other.latitude);
double sinLat = Math.sin(dLat / 2);
double sinLon = Math.sin(dLon / 2);
double a = sinLat * sinLat + Math.cos(lat1) * Math.cos(lat2) * sinLon * sinLon;
double c = 2 * MathUtil.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return EARTH_RADIUS_METERS * c;
}

/// {@inheritDoc}
@Override
public boolean equals(Object o) {
if (!(o instanceof LatLng)) {
return false;
}
LatLng l = (LatLng) o;
return Math.abs(latitude - l.latitude) < DELTA
&& Math.abs(longitude - l.longitude) < DELTA;
}

/// {@inheritDoc}
@Override
public int hashCode() {
long lat = Double.doubleToLongBits(latitude);
long lon = Double.doubleToLongBits(longitude);
int hash = 7;
hash = 31 * hash + (int) (lat ^ (lat >>> 32));
hash = 31 * hash + (int) (lon ^ (lon >>> 32));
return hash;
}

/// {@inheritDoc}
@Override
public String toString() {
return "LatLng{" + latitude + ", " + longitude + "}";
}
}
Loading
Loading