geodata는 GeoJSON 및 OGC API Features 데이터 소스를 효율적으로 읽고 처리하기 위해 설계된 Flutter/Dart 패키지입니다. 다양한 플랫폼에서 지리공간 데이터를 가져오고 파싱하며 작업할 수 있도록 가볍고 일관된 인터페이스를 제공합니다. 지도 기반 데이터 통합이 필요한 애플리케이션에 적합하며, Android, iOS, Web, macOS, Windows, Linux에서 원활하게 사용할 수 있습니다. 지리적 특성의 처리를 간소화하여 개발자가 최소한의 보일러플레이트로 위치 기반 앱을 구축할 수 있게 해줍니다.
사용 사례
모바일 및 웹 앱에서 GeoJSON 지도 통합
OGC API를 통해 실시간 지리공간 데이터 가져오기
인터랙티브 지도 인터페이스 구축
크로스 플랫폼 앱에서 공간 데이터 세트 처리하기
벡터 기반 지리적 특징 표시
주요 기능
GeoJSON 및 OGC API Features를 지원합니다
크로스 플랫폼 호환성
경량이며 쉽게 통합할 수 있음
내장된 구문 분석 및 데이터 처리
기능 검색을 위한 개선된 API
적합한 대상
GIS 애플리케이션을 개발하는 개발자
동적 지도 데이터가 필요한 앱
크로스 플랫폼 위치 기반 프로젝트
OGC 표준을 사용하는 팀
공간 데이터를 사용하는 프론트엔드 개발자
고려 사항
유효한 GeoJSON 또는 OGC API 엔드포인트가 필요합니다
읽기 전용 데이터만 가능—쓰기 기능 없음
원격 소스를 위해 네트워크 연결에 의존합니다
시각화를 위해 추가적인 스타일링이 필요할 수 있습니다
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
:compass: Geospatial tools for Dart
Geospatial data structures, tools and utilities for
Dart and Flutter - coordinates,
geometries, feature objects, metadata, spherical geodesy, projections, tiling
schemes, vector data models and formats, and geospatial Web APIs.
✨ New (2024-11-10): The stable release with ellipsoidal geodesy functions letting you calculate distances, bearings, destination positions and intermediate points along the Earth surface accurately.
✨ New (2024-07-26): The stable version 1.3.0 with centroid, polylabel, point-in-polygon and other cartesian 2D calculations enhanced - read more!
Geospatial data structures (coordinates, geometries, features, metadata), ellipsoidal and spherical geodesy, projections and tiling schemes. Vector data format support for GeoJSON, WKT and WKB.
Partially supported (conformance classes, queryables, features filter).
:keyboard: Sample code
Geodesy functions with geobase
Ellipsoidal and spherical geodesy functions to calculate distances etc.:
final greenwich = Geographic.parseDms(lat: '51°28′40″ N', lon: '0°00′05″ W');
final sydney = Geographic.parseDms(lat: '33.8688° S', lon: '151.2093° E');
// How to calculate distances using ellipsoidal Vincenty, spherical// great-circle and spherical rhumb line methods is shown first.// The distance along a geodesic on the ellipsoid surface (16983.3 km).
greenwich.vincenty().distanceTo(sydney);
// By default the WGS84 reference ellipsoid is used but this can be changed.
greenwich.vincenty(ellipsoid: Ellipsoid.GRS80).distanceTo(sydney);
// The distance along a spherical great-circle path (16987.9 km).
greenwich.spherical.distanceTo(sydney);
// The distance along a spherical rhumb line path (17669.8 km).
greenwich.rhumb.distanceTo(sydney);
// Also bearings, destination points and mid points (or intermediate points)// are provided for all methods, but below shown only for great-circle paths.// Destination point (10 km to bearing 61°): 51° 31.3′ N, 0° 07.5′ E
greenwich.spherical.initialBearingTo(sydney);
greenwich.spherical.finalBearingTo(sydney);
// Destination point: 51° 31.3′ N, 0° 07.5′ E
greenwich.spherical.destinationPoint(distance: 10000, bearing: 61.0);
// Midpoint: 28° 34.0′ N, 104° 41.6′ E
greenwich.spherical.midPointTo(sydney);
// Vincenty ellipsoidal geodesy functions provide also `inverse` and `direct`// methods to calculate shortest arcs along a geodesic on the ellipsoid. The// returned arc object contains origin and destination points, initial and// final bearings, and distance between points.
greenwich.vincenty().inverse(sydney);
greenwich.vincenty().direct(distance: 10000, bearing: 61.0);
Geospatial data structures with geobase
As a quick sample, this is how geometry objects with 2D coordinate are created
using geobase:
Geospatial feature and feature collections can be instantiated easily too:
// A geospatial feature collection (with two features):FeatureCollection([
Feature(
id: 'ROG',
// a point geometry with a position (lon, lat, elev)
geometry: Point.build([-0.0014, 51.4778, 45.0]),
properties: {
'title': 'Royal Observatory',
'city': 'London',
'isMuseum': true,
},
),
Feature(
id: 'TB',
// a point geometry with a position (lon, lat)
geometry: Point.build([-0.075406, 51.5055]),
properties: {
'title': 'Tower Bridge',
'built': 1886,
},
),
]);
GeoJSON, WKT and WKB formats are supported as input and output:
// Parse a geometry from GeoJSON text.final geometry = LineString.parse(
'{"type": "LineString", "coordinates": [[30,10],[10,30],[40,40]]}',
format: GeoJSON.geometry,
);
// Encode a geometry as GeoJSON text.print(geometry.toText(format: GeoJSON.geometry));
// Encode a geometry as WKT text.print(geometry.toText(format: WKT.geometry));
// Encode a geometry as WKB bytes.final bytes = geometry.toBytes(format: WKB.geometry);
// Decode a geometry from WKB bytes.LineString.decode(bytes, format: WKB.geometry);
A sample showing more deeply how to handle WKB and EWKB binary data:
// to get a sample point, first parse a 3D point from WKT encoded stringfinal p = Point.parse('POINT Z(-0.0014 51.4778 45)', format: WKT.geometry);
// to encode a geometry as WKB/EWKB use toBytes() or toBytesHex() methods// encode as standard WKB data (format: `WKB.geometry`), prints:// 01e9030000c7bab88d06f056bfb003e78c28bd49400000000000804640final wkbHex = p.toBytesHex(format: WKB.geometry);
print(wkbHex);
// encode as Extended WKB data (format: `WKB.geometryExtended`), prints:// 0101000080c7bab88d06f056bfb003e78c28bd49400000000000804640final ewkbHex = p.toBytesHex(format: WKB.geometryExtended);
print(ewkbHex);
// otherwise encoded data equals, but bytes for the geometry type varies// there are some helper methods to analyse WKB/EWKB bytes or hex strings// (decodeFlavor, decodeEndian, decodeSRID and versions with hex postfix)// prints: "WkbFlavor.standard - WkbFlavor.extended"print('${WKB.decodeFlavorHex(wkbHex)} - ${WKB.decodeFlavorHex(ewkbHex)}');
// when decoding WKB or EWKB data, a variant is detected automatically, so// both `WKB.geometry` and `WKB.geometryExtended` can be usedfinal pointFromWkb = Point.decodeHex(wkbHex, format: WKB.geometry);
final pointFromEwkb = Point.decodeHex(ewkbHex, format: WKB.geometry);
print(pointFromWkb.equals3D(pointFromEwkb)); // prints "true"// SRID can be encoded only on EWKB data, this sample prints:// 01010000a0e6100000c7bab88d06f056bfb003e78c28bd49400000000000804640final ewkbHexWithSRID =
p.toBytesHex(format: WKB.geometryExtended, crs: CoordRefSys.EPSG_4326);
print(ewkbHexWithSRID);
// if you have WKB or EWKB data, but not sure which, then you can fist check// a flavor and whether it contains SRID, prints: "SRID from EWKB data: 4326"if (WKB.decodeFlavorHex(ewkbHexWithSRID) == WkbFlavor.extended) {
final srid = WKB.decodeSRIDHex(ewkbHexWithSRID);
if (srid != null) {
print('SRID from EWKB data: $srid');
// after finding out CRS, an actual point can be decoded// Point.decodeHex(ewkbHexWithSRID, format: WKB.geometry);
}
}
Using Newline-delimited GeoJSON (or "GeoJSONL") is as easy as using the
standard GeoJSON:
/// a feature collection encoded as GeoJSONL and containing two features that/// are delimited by the newline character \nconst sample = '''
{"type":"Feature","id":"ROG","geometry":{"type":"Point","coordinates":[-0.0014,51.4778,45]},"properties":{"title":"Royal Observatory","place":"Greenwich"}}
{"type":"Feature","id":"TB","geometry":{"type":"Point","coordinates":[-0.075406,51.5055]},"properties":{"title":"Tower Bridge","built":1886}}
''';
// parse a FeatureCollection object using the decoder for the GeoJSONL formatfinal collection = FeatureCollection.parse(sample, format: GeoJSONL.feature);
// ... use features read and returned in a feature collection object ...// encode back to GeoJSONL dataprint(collection.toText(format: GeoJSONL.feature, decimals: 5));
Access GeoJSON resources with geodata
The geodata package has the following
diagram describing a decision flowchart how to select a client class to access
GeoJSON features:
Quick start code to access a Web API service conforming to OGC API Features:
// 1. Get a client instance for a Web API endpoint.final client = OGCAPIFeatures.http(endpoint: Uri.parse('...'));
// 2. Access/check metadata (meta, OpenAPI, conformance, collections) as needed.final conformance = await client.conformance();
if (!conformance.conformsToFeaturesCore(geoJSON: true)) {
return; // not conforming to core and GeoJSON - so return
}
// 3. Get a feature source for a specific collection.final source = await client.collection('my_collection');
// 4. Access (and check) metadata for this collection.final meta = await source.meta();
print('Collection title: ${meta.title}');
// 5. Access feature items.final items = await source.itemsAll(limit: 100);
// 6. Check response metadata.print('Timestamp: ${items.timeStamp}');
// 7. Get an iterable of feature objects.final features = items.collection.features;
// 8. Loop through features (each with id, properties and geometry)for (final feat in features) {
print('Feature ${feat.id} with geometry: ${feat.geometry}');
}
:rocket: Demos and samples
More guidance and code examples are provided on the
geospatial.navibyte.dev documentation site.
✨ See also the
Geospatial demos for Dart code
repository for demo and sample apps demonstrating the usage of
geobase and
geodata packages along with other topics.
Shows earthquakes fetched from the USGS web service on a basic map view. The demo uses both geobase and geodata packages for geospatial data accesss. Discusses also state management based on Riverpod. The map UI is based on the Google Maps Flutter plugin.
✨ The stable release with ellipsoidal geodesy functions letting you calculate distances, bearings, destination positions and intermediate points along the Earth surface accurately.
Proj4dart is a Dart library to transform point coordinates from one coordinate system to another, including datum transformations (Dart version of proj4js/proj4js).