Skip to content

Commit

Permalink
Merge pull request #693 from openmobilemaps/release/3.0.1
Browse files Browse the repository at this point in the history
Release 3.0.1
  • Loading branch information
maurhofer-ubique authored Feb 28, 2025
2 parents 869bc72 + ceb39f7 commit 3e984eb
Show file tree
Hide file tree
Showing 21 changed files with 84 additions and 47 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog for Open Mobile Maps

## Version 3.0.1
- Add minZoom/extent (for virtual tiles) option for geojson sources in style jsons
- Changed some static vectors to thread-local vectors to avoid potential data races
- Fixes a bug in iOS polygon position offset calculation
- Catch c++ future exception if the promise is deallocated while the its not fulfilled

## Version 3.0.0
- Introduced 3D globe rendering with support for most established layers and features and a custom camera and configuration options
- Massively improved the spatial precision of the map
Expand Down
4 changes: 2 additions & 2 deletions android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ SNAPSHOT_REPOSITORY_URL=https://oss.sonatype.org/content/repositories/snapshots/

GROUP=io.openmobilemaps
POM_ARTIFACT_ID=mapscore
VERSION_NAME=3.0.0
VERSION_CODE=3000000
VERSION_NAME=3.0.1
VERSION_CODE=3000100

POM_NAME=mapscore
POM_PACKAGING=aar
Expand Down
2 changes: 1 addition & 1 deletion android/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ This library is available on MavenCentral. To add it to your Android project, ad

```
dependencies {
implementation 'io.openmobilemaps:mapscore:3.0.0'
implementation 'io.openmobilemaps:mapscore:3.0.1'
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ open class AssetLocalDataProvider(

override fun loadGeojson(sourceName: String, url: String): Future<DataLoaderResult> {
return loadDataAsync?.invoke(url, null) ?: Promise<DataLoaderResult>().apply {
Log.e(AssetLocalDataProvider::class.java.canonicalName, "Failed to load geojson for url: $url")
setValue(
DataLoaderResult(
null,
Expand Down
15 changes: 7 additions & 8 deletions ios/graphics/Model/Polygon/PolygonGroup2d.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,13 @@ extension PolygonGroup2d: MCPolygonGroup2dInterface {
var minY = Float.greatestFiniteMagnitude

if shader.isStriped {
if let p = UnsafeRawPointer(bitPattern: Int(vertices.address)) {
for i in 0 ..< vertices.elementCount {
if i % 3 == 0 {
let x = (p + 4 * Int(i)).load(as: Float.self)
let y = (p + 4 * (Int(i) + 1)).load(as: Float.self)
minX = min(x, minX)
minY = min(y, minY)
}
let count = Int(vertices.elementCount / 4)
if let rawPointer = UnsafeRawPointer(bitPattern: Int(vertices.address)) {
let float4Pointer = rawPointer.assumingMemoryBound(to: SIMD4<Float>.self)
for i in 0 ..< count {
let value = float4Pointer[i]
minX = min(value.x, minX)
minY = min(value.y, minY)
}
}
}
Expand Down
15 changes: 7 additions & 8 deletions ios/graphics/Model/Polygon/PolygonPatternGroup2d.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,13 @@ extension PolygonPatternGroup2d: MCPolygonPatternGroup2dInterface {
var minX = Float.greatestFiniteMagnitude
var minY = Float.greatestFiniteMagnitude

if let p = UnsafeRawPointer(bitPattern: Int(vertices.address)) {
for i in 0 ..< vertices.elementCount {
if i % 3 == 0 {
let x = (p + 4 * Int(i)).load(as: Float.self)
let y = (p + 4 * (Int(i) + 1)).load(as: Float.self)
minX = min(x, minX)
minY = min(y, minY)
}
if let rawPointer = UnsafeRawPointer(bitPattern: Int(vertices.address)) {
let count = Int(vertices.elementCount / 4)
let float4Pointer = rawPointer.assumingMemoryBound(to: SIMD4<Float>.self)
for i in 0 ..< count {
let value = float4Pointer[i]
minX = min(value.x, minX)
minY = min(value.y, minY)
}
}
lock.withCritical {
Expand Down
2 changes: 1 addition & 1 deletion ios/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ For App integration within XCode, add this package to your App target. To do thi
Once you have your Swift package set up, adding Open Mobile Maps as a dependency is as easy as adding it to the dependencies value of your Package.swift.
```swift
dependencies: [
.package(url: "https://github.com/openmobilemaps/maps-core", from: .init(stringLiteral: "3.0.0"))
.package(url: "https://github.com/openmobilemaps/maps-core", from: .init(stringLiteral: "3.0.1"))
]
```

Expand Down
12 changes: 6 additions & 6 deletions shared/public/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class WeakActor {
if (strongObject && strongMailbox) {
strongMailbox->push(makeMessage(MailboxDuplicationStrategy::none, MailboxExecutionEnvironment::computation, object, fn, std::forward<Args>(args)...));
} else {
LogError <<= "WeakActor holds nullptr";
LogError << "WeakActor holds nullptr: " <<= fn.diagnostics.toString();
}
}

Expand All @@ -98,7 +98,7 @@ class WeakActor {
if (strongObject && strongMailbox) {
strongMailbox->push(makeMessage(strategy, MailboxExecutionEnvironment::computation, object, fn, std::forward<Args>(args)...));
} else {
LogError <<= "WeakActor holds nullptr";
LogError << "WeakActor holds nullptr: " <<= fn.diagnostics.toString();
}
}

Expand All @@ -109,7 +109,7 @@ class WeakActor {
if (strongObject && strongMailbox) {
strongMailbox->push(makeMessage(MailboxDuplicationStrategy::none, environment, object, fn, std::forward<Args>(args)...));
} else {
LogError <<= "WeakActor holds nullptr";
LogError << "WeakActor holds nullptr: " <<= fn.diagnostics.toString();
}
}

Expand All @@ -120,7 +120,7 @@ class WeakActor {
if (strongObject && strongMailbox) {
strongMailbox->push(makeMessage(strategy, environment, object, fn, std::forward<Args>(args)...));
} else {
LogError <<= "WeakActor holds nullptr";
LogError << "WeakActor holds nullptr: " <<= fn.diagnostics.toString();
}
}

Expand All @@ -138,7 +138,7 @@ class WeakActor {
if (strongObject && strongMailbox) {
strongMailbox->push(makeAskMessage(MailboxDuplicationStrategy::none, MailboxExecutionEnvironment::computation, std::move(promise), object, fn, std::forward<Args>(args)...));
} else {
LogError <<= "WeakActor holds nullptr";
LogError << "WeakActor holds nullptr: " <<= fn.diagnostics.toString();
}
return future;
}
Expand All @@ -156,7 +156,7 @@ class WeakActor {
if (strongObject && strongMailbox) {
strongMailbox->push(makeAskMessage(MailboxDuplicationStrategy::none, environment, std::move(promise), object, fn, std::forward<Args>(args)...));
} else {
LogError <<= "WeakActor holds nullptr";
LogError << "WeakActor holds nullptr: " <<= fn.diagnostics.toString();
}
return future;
}
Expand Down
2 changes: 1 addition & 1 deletion shared/public/LoaderHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class LoaderHelper {
if (loaderIndex >= loaders.size()) {
promise->setValue(DataLoaderResult(std::nullopt, std::nullopt, LoaderStatus::NOOP, std::nullopt));
} else {
loaders[loaderIndex]->loadDataAsync(url, etag).then([url, etag, &loaders, loaderIndex, promise](::djinni::Future<::DataLoaderResult> result) {
loaders[loaderIndex]->loadDataAsync(url, etag).then([url, etag, loaders, loaderIndex, promise](::djinni::Future<::DataLoaderResult> result) {
const auto dataResult = result.get();
if (dataResult.status != LoaderStatus::NOOP || loaderIndex == loaders.size() - 1) {
promise->setValue(std::move(dataResult));
Expand Down
2 changes: 1 addition & 1 deletion shared/src/MapsCoreSharedModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@

#include "MapsCoreSharedModule.h"

std::string MapsCoreSharedModule::version() { return "3.0.0"; }
std::string MapsCoreSharedModule::version() { return "3.0.1"; }
4 changes: 2 additions & 2 deletions shared/src/map/layers/effect/SphereEffectLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ void SphereEffectLayer::update() {
return;
}

static std::vector<double> coefficients(16, 0.0);
static std::vector<float> coefficientsFloat(16, 0.0);
thread_local std::vector<double> coefficients(16, 0.0);
thread_local std::vector<float> coefficientsFloat(16, 0.0);

castedCamera->computeEllipseCoefficients(coefficients);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ class Tiled2dMapVectorGeoJSONLayerConfig : public Tiled2dMapVectorLayerConfig {

std::vector<Tiled2dMapZoomLevelInfo> getZoomLevelInfos() override {
int maxZoom = 0;
int minZoom = 0;
if (auto geoJSON = this->geoJSON.lock()){
minZoom = geoJSON->getMinZoom();
maxZoom = geoJSON->getMaxZoom();
}
return getDefaultEpsg3857ZoomLevels(0, maxZoom);
return getDefaultEpsg3857ZoomLevels(minZoom, maxZoom);
}

std::vector<Tiled2dMapZoomLevelInfo> getVirtualZoomLevelInfos() override {
Expand Down
18 changes: 15 additions & 3 deletions shared/src/map/layers/tiled/vector/Tiled2dMapVectorLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ void Tiled2dMapVectorLayer::onRenderPassUpdate(const std::string &source, bool i
}

void Tiled2dMapVectorLayer::pregenerateRenderPasses() {
static std::vector<std::shared_ptr<RenderPassInterface>> newPasses;
thread_local std::vector<std::shared_ptr<RenderPassInterface>> newPasses;
newPasses.clear();

if (backgroundLayer) {
Expand Down Expand Up @@ -1155,7 +1155,13 @@ void Tiled2dMapVectorLayer::updateLayerDescription(std::shared_ptr<VectorLayerDe

std::optional<std::shared_ptr<FeatureContext>> Tiled2dMapVectorLayer::getFeatureContext(int64_t identifier) {
for (const auto &[source, vectorTileSource] : vectorTileSources) {
auto const &currentTileInfos = vectorTileSource.converse(MFN(&Tiled2dMapVectorSource::getCurrentTiles)).get();
VectorSet<Tiled2dMapVectorTileInfo> currentTileInfos;
try {
currentTileInfos = vectorTileSource.converse(MFN(&Tiled2dMapVectorSource::getCurrentTiles)).get();
} catch (const std::exception &e) {
LogError << "Exception while getting future result: " <<= e.what();
continue;
}

for (auto const &tile: currentTileInfos) {
for (auto it = tile.layerFeatureMaps->begin(); it != tile.layerFeatureMaps->end(); it++) {
Expand Down Expand Up @@ -1390,7 +1396,13 @@ std::vector<VectorLayerFeatureCoordInfo> Tiled2dMapVectorLayer::getVisiblePointF
std::vector<VectorLayerFeatureCoordInfo> features = {};

for (const auto &[source, vectorTileSource] : vectorTileSources) {
auto const &currentTileInfos = vectorTileSource.converse(MFN(&Tiled2dMapVectorSource::getCurrentTiles)).get();
VectorSet<Tiled2dMapVectorTileInfo> currentTileInfos;
try {
currentTileInfos = vectorTileSource.converse(MFN(&Tiled2dMapVectorSource::getCurrentTiles)).get();
} catch (const std::exception &e) {
LogError << "Exception while getting future result: " <<= e.what();
continue;
}

for (auto const &tile: currentTileInfos) {
for (auto it = tile.layerFeatureMaps->begin(); it != tile.layerFeatureMaps->end(); it++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ Tiled2dMapVectorLayerParserResult Tiled2dMapVectorLayerParserHelper::parseStyleJ
if (val["maxzoom"].is_number_integer()) {
options.maxZoom = val["maxzoom"].get<uint8_t>();
}
if (val["extent"].is_number_integer()) {
options.extent = val["extent"].get<uint32_t>();
}
if (val["data"].is_string()) {
geojsonSources[key] = GeoJsonVTFactory::getGeoJsonVt(key, replaceUrlParams(val["data"].get<std::string>(), sourceUrlParams), loaders, localDataProvider, options);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Tiled2dVectorGeoJsonSource : public Tiled2dMapVectorSource, public GeoJSON
auto bounds = camera->getVisibleRect();
auto zoom = camera->getZoom();
// there is no concept of curT for geoJSON, therefore we just set it to 0
lastVisibleTilesHash = 0;
onVisibleBoundsChanged(bounds, 0, zoom);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ struct TileOptions {
double tolerance = 1.0;

// tile extent
uint16_t extent = 4096;
uint32_t extent = 4096;

// tile buffer on each side
uint16_t buffer = 64;
uint32_t buffer = 64;
};

struct Options : TileOptions {
Expand Down Expand Up @@ -87,6 +87,7 @@ class GeoJSONVT: public GeoJSONVTInterface, public std::enable_shared_from_this<
if (!self) return;
auto result = resultFuture.get();

self->loadingResult = DataLoaderResult(std::nullopt, std::nullopt, result.status, result.errorCode);
if (result.status != LoaderStatus::OK) {
LogError <<= "Unable to load geoJson";

Expand Down Expand Up @@ -116,7 +117,6 @@ class GeoJSONVT: public GeoJSONVTInterface, public std::enable_shared_from_this<
return;
}
}
self->loadingResult = DataLoaderResult(std::nullopt, std::nullopt, result.status, result.errorCode);
self->loaders.clear();

self->resolveAllWaitingPromises();
Expand Down
4 changes: 2 additions & 2 deletions shared/src/map/layers/tiled/vector/geojson/geojsonvt/tile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct Tile: public GeoJSONTileInterface {

class InternalTile {
public:
const uint16_t extent;
const uint32_t extent;
const uint8_t z;
const uint32_t x;
const uint32_t y;
Expand All @@ -38,7 +38,7 @@ class InternalTile {
const uint8_t z_,
const uint32_t x_,
const uint32_t y_,
const uint16_t extent_,
const uint32_t extent_,
const double tolerance_)
: extent(extent_),
z(z_),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ Tiled2dMapVectorSourceDataManager::Tiled2dMapVectorSourceDataManager(const WeakA
}
}

readyManagerIndex = readyManager.converse(MFN(&Tiled2dMapVectorReadyManager::registerManager)).get();
try {
readyManagerIndex = readyManager.converse(MFN(&Tiled2dMapVectorReadyManager::registerManager)).get();
} catch (const std::exception &e) {
LogError << "Exception while getting future result: " <<= e.what();
}
}

void Tiled2dMapVectorSourceDataManager::onAdded(const std::weak_ptr<::MapInterface> &mapInterface) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,13 @@ void Tiled2dMapVectorSourceRasterTileDataManager::updateLayerDescription(std::sh
return;
}

auto const &currentTileInfos = rasterSource.converse(MFN(&Tiled2dMapRasterSource::getCurrentTiles)).get();
VectorSet<Tiled2dMapRasterTileInfo> currentTileInfos;
try {
currentTileInfos = rasterSource.converse(MFN(&Tiled2dMapRasterSource::getCurrentTiles)).get();
} catch (const std::exception &e) {
LogError << "Exception while getting future result: " <<= e.what();
return;
}

std::unordered_set<Tiled2dMapTileInfo> currentTilesStrippedInfos;
for (const auto &tile : currentTileInfos) {
Expand Down Expand Up @@ -297,7 +303,13 @@ void Tiled2dMapVectorSourceRasterTileDataManager::reloadLayerContent(
return;
}

auto const &currentTileInfos = rasterSource.converse(MFN(&Tiled2dMapRasterSource::getCurrentTiles)).get();
VectorSet<Tiled2dMapRasterTileInfo> currentTileInfos;
try {
currentTileInfos = rasterSource.converse(MFN(&Tiled2dMapRasterSource::getCurrentTiles)).get();
} catch (const std::exception &e) {
LogError << "Exception while getting future result: " <<= e.what();
return;
}

std::unordered_set<Tiled2dMapTileInfo> currentTilesStrippedInfos;
for (const auto &tile : currentTileInfos) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,10 +348,8 @@ void Tiled2dMapVectorSymbolLabelObject::updatePropertiesPoint(std::vector<float>

Vec2D anchorOffset(0.0, 0.0);

static std::vector<double> baseLines;
while(baseLines.size() < characterCount) {
baseLines.push_back(0.0);
}
thread_local std::vector<double> baseLines;
baseLines.resize(characterCount, 0.0);

float yOffset = 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void Tiled2dMapVectorPolygonTile::update() {
size_t numStyleGroups = featureGroups.size();
for (int styleGroupId = 0; styleGroupId < numStyleGroups; styleGroupId++) {
std::vector<float> shaderStyles;
shaderStyles.reserve(featureGroups.at(styleGroupId).size() * 5);
shaderStyles.reserve(featureGroups.at(styleGroupId).size() * (isStriped ? 7 : 5));
for (auto const &[hash, feature]: featureGroups.at(styleGroupId)) {
const auto& ec = EvaluationContext(zoomIdentifier, dpFactor, feature, featureStateManager);
const auto& color = inZoomRange ? polygonDescription->style.getFillColor(ec) : Color(0.0, 0.0, 0.0, 0.0);
Expand Down

0 comments on commit 3e984eb

Please sign in to comment.