make packages for dart and npm
This commit is contained in:
@@ -0,0 +1 @@
|
||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"geolocator_apple","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.13/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"maplibre_gl","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/maplibre_gl-0.19.0+2/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"geolocator_android","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/geolocator_android-4.6.2/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"maplibre_gl","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/maplibre_gl-0.19.0+2/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"geolocator_apple","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/geolocator_apple-2.3.13/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[],"windows":[{"name":"geolocator_windows","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/geolocator_windows-0.2.5/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"geolocator_web","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/geolocator_web-2.2.1/","dependencies":[],"dev_dependency":false},{"name":"maplibre_gl_web","path":"/Users/hamzaaleghwairyeen/.pub-cache/hosted/pub.dev/maplibre_gl_web-0.19.0+2/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"geolocator","dependencies":["geolocator_android","geolocator_apple","geolocator_web","geolocator_windows"]},{"name":"geolocator_android","dependencies":[]},{"name":"geolocator_apple","dependencies":[]},{"name":"geolocator_web","dependencies":[]},{"name":"geolocator_windows","dependencies":[]},{"name":"maplibre_gl","dependencies":["maplibre_gl_web"]},{"name":"maplibre_gl_web","dependencies":[]}],"date_created":"2026-04-16 16:50:12.143766","version":"3.32.8","swift_package_manager_enabled":{"ios":false,"macos":false}}
|
||||
@@ -0,0 +1,7 @@
|
||||
## 1.0.0
|
||||
|
||||
* Initial release of the Intaleq Maps Foundation SDK.
|
||||
* Support for Markers, Polylines, Circles, and Polygons (with holes).
|
||||
* Integrated Intaleq Routing and Geocoding APIs.
|
||||
* Built-in premium map styles (Obsidian, Light, Satellite).
|
||||
* Integrated Polyline decoding utility.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Intaleq
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Intaleq Maps SDK for Flutter
|
||||
|
||||
A premium Flutter SDK for the Intaleq Map Platform, optimized for Jordan, Syria, and the broader region. This SDK provides a simplified, developer-friendly interface over MapLibre GL, with built-in support for Intaleq's Routing and Geocoding APIs.
|
||||
|
||||
## Features
|
||||
|
||||
- **Simplified Geometry**: Use `Marker`, `Polyline`, `Circle`, and `Polygon` (with hole support) instead of complex low-level types.
|
||||
- **Intaleq Routing**: Integrated multi-profile routing API.
|
||||
- **Intaleq Geocoding**: High-performance place search and reverse geocoding.
|
||||
- **Branding-Ready**: Built-in Intaleq branding colors and premium map styles (Obsidian, Light, Satellite).
|
||||
- **Standalone**: No external dependencies required for route decoding.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Add the following to your `pubspec.yaml`:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
intaleq_maps: ^1.0.0
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Initialize the Map
|
||||
|
||||
```dart
|
||||
IntaleqMap(
|
||||
apiKey: "YOUR_INTALEQ_API_KEY",
|
||||
onMapCreated: (controller) {
|
||||
// Access the controller here
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
### Add a Marker
|
||||
|
||||
```dart
|
||||
await controller.addMarker(MarkerOptions(
|
||||
position: LatLng(33.5138, 36.2765),
|
||||
iconImage: "marker-icon",
|
||||
));
|
||||
```
|
||||
|
||||
### Get a Route
|
||||
|
||||
```dart
|
||||
final routeData = await controller.getRoute(
|
||||
LatLng(33.5138, 36.2765),
|
||||
LatLng(33.5, 36.3),
|
||||
);
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
For full documentation and API reference, visit the [Intaleq Documentation](https://map-dashbord.intaleqapp.com/dashboard.html#docs).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
@@ -1,49 +1,10 @@
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
library intaleq_maps;
|
||||
|
||||
class IntaleqMapController {
|
||||
final MapLibreMapController mapController;
|
||||
final String apiKey;
|
||||
export 'package:maplibre_gl/maplibre_gl.dart' show LatLng, LatLngBounds, CameraUpdate, CameraPosition, Symbol, Line, Circle, Fill;
|
||||
|
||||
IntaleqMapController({
|
||||
required this.mapController,
|
||||
required this.apiKey,
|
||||
});
|
||||
|
||||
/// Search for places using Intaleq Geocoding API
|
||||
Future<List<dynamic>> search(String query) async {
|
||||
final response = await http.get(
|
||||
Uri.parse(
|
||||
'https://map-saas.intaleq.com/v1/geocoding/search?q=$query&key=$apiKey'),
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
return json.decode(response.body);
|
||||
}
|
||||
throw Exception('Failed to search');
|
||||
}
|
||||
|
||||
/// Get route using Intaleq Routing API
|
||||
Future<Map<String, dynamic>> getRoute(
|
||||
LatLng start,
|
||||
LatLng end, {
|
||||
String profile = 'car',
|
||||
}) async {
|
||||
final response = await http.get(
|
||||
Uri.parse(
|
||||
'https://map-saas.intaleq.com/v1/routing/route?start=${start.longitude},${start.latitude}&end=${end.longitude},${end.latitude}&profile=$profile&key=$apiKey',
|
||||
),
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
return json.decode(response.body);
|
||||
}
|
||||
throw Exception('Failed to fetch route');
|
||||
}
|
||||
}
|
||||
|
||||
class IntaleqStyles {
|
||||
static String obsidian(String apiKey) =>
|
||||
'https://maps.intaleq.com/styles/obsidian/style.json?key=$apiKey';
|
||||
static String light(String apiKey) =>
|
||||
'https://maps.intaleq.com/styles/light/style.json?key=$apiKey';
|
||||
}
|
||||
export 'src/intaleq_map_controller.dart';
|
||||
export 'src/intaleq_map_widget.dart';
|
||||
export 'src/styles.dart';
|
||||
export 'src/models/geometry.dart';
|
||||
export 'src/utils/polyline_utils.dart';
|
||||
export 'src/constants/colors.dart';
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
class IntaleqColors {
|
||||
/// The signature Intaleq Blue color.
|
||||
static const String primaryBlue = '#0D47A1';
|
||||
|
||||
/// Cyan used for remaining route lines.
|
||||
static const String routeCyan = '#00e5ff';
|
||||
|
||||
/// Gray used for traveled paths or alternatives.
|
||||
static const String softGray = '#BDBDBD';
|
||||
|
||||
/// Semi-transparent gray for polygon fills.
|
||||
static const String fillGray = '#BDBDBD33'; // 20% opacity
|
||||
|
||||
/// Red for error or stop states.
|
||||
static const String alertRed = '#ba1a1a';
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:maplibre_gl/maplibre_gl.dart' hide CircleOptions;
|
||||
import 'models/geometry.dart';
|
||||
|
||||
class IntaleqMapController {
|
||||
final MaplibreMapController mapController;
|
||||
final String apiKey;
|
||||
|
||||
IntaleqMapController({
|
||||
required this.mapController,
|
||||
required this.apiKey,
|
||||
});
|
||||
|
||||
// --- API Integrations ---
|
||||
|
||||
/// Search for places using Intaleq Geocoding API
|
||||
Future<List<dynamic>> search(String query) async {
|
||||
final response = await http.get(
|
||||
Uri.parse('https://map-saas.intaleq.com/v1/geocoding/search?q=$query&key=$apiKey'),
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
return json.decode(response.body);
|
||||
}
|
||||
throw Exception('Failed to search');
|
||||
}
|
||||
|
||||
/// Get route using Intaleq Routing API
|
||||
Future<Map<String, dynamic>> getRoute(LatLng start, LatLng end, {String profile = 'driving'}) async {
|
||||
final response = await http.get(
|
||||
Uri.parse(
|
||||
'https://map-saas.intaleq.com/v1/routing/route?start=${start.longitude},${start.latitude}&end=${end.longitude},${end.latitude}&profile=$profile&key=$apiKey',
|
||||
),
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
return json.decode(response.body);
|
||||
}
|
||||
throw Exception('Failed to fetch route');
|
||||
}
|
||||
|
||||
// --- Friendly Abstractions (Transformation Layer) ---
|
||||
|
||||
/// Add a marker (friendly wrapper for addSymbol)
|
||||
Future<Symbol> addMarker(MarkerOptions options) async {
|
||||
return await mapController.addSymbol(options.toSymbolOptions());
|
||||
}
|
||||
|
||||
/// Add multiple markers
|
||||
Future<List<Symbol>> addMarkers(List<MarkerOptions> optionsList) async {
|
||||
final symbols = <Symbol>[];
|
||||
for (var options in optionsList) {
|
||||
symbols.add(await addMarker(options));
|
||||
}
|
||||
return symbols;
|
||||
}
|
||||
|
||||
/// Remove a marker
|
||||
Future<void> removeMarker(Symbol marker) async {
|
||||
await mapController.removeSymbol(marker);
|
||||
}
|
||||
|
||||
/// Add a polyline (friendly wrapper for addLine)
|
||||
Future<Line> addPolyline(PolylineOptions options) async {
|
||||
return await mapController.addLine(options.toLineOptions());
|
||||
}
|
||||
|
||||
/// Remove a polyline
|
||||
Future<void> removePolyline(Line polyline) async {
|
||||
await mapController.removeLine(polyline);
|
||||
}
|
||||
|
||||
/// Add a circle
|
||||
Future<Circle> addCircle(CircleOptions options) async {
|
||||
return await mapController.addCircle(options.toMapLibreOptions());
|
||||
}
|
||||
|
||||
/// Remove a circle
|
||||
Future<void> removeCircle(Circle circle) async {
|
||||
await mapController.removeCircle(circle);
|
||||
}
|
||||
|
||||
/// Add a polygon (Fill)
|
||||
Future<Fill> addPolygon(PolygonOptions options) async {
|
||||
return await mapController.addFill(options.toFillOptions());
|
||||
}
|
||||
|
||||
/// Remove a polygon
|
||||
Future<void> removePolygon(Fill polygon) async {
|
||||
await mapController.removeFill(polygon);
|
||||
}
|
||||
|
||||
/// Clear all map objects
|
||||
void clearAll() {
|
||||
mapController.clearSymbols();
|
||||
mapController.clearLines();
|
||||
mapController.clearCircles();
|
||||
mapController.clearFills();
|
||||
}
|
||||
|
||||
// --- Camera Controls ---
|
||||
|
||||
void animateCameraTo(LatLng position, {double? zoom}) {
|
||||
mapController.animateCamera(CameraUpdate.newLatLngZoom(position, zoom ?? mapController.cameraPosition?.zoom ?? 14.0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
import 'intaleq_map_controller.dart';
|
||||
import 'styles.dart';
|
||||
|
||||
typedef MapCreatedCallback = void Function(IntaleqMapController controller);
|
||||
|
||||
class IntaleqMap extends StatefulWidget {
|
||||
final String apiKey;
|
||||
final String? styleUrl;
|
||||
final LatLng initialPosition;
|
||||
final double initialZoom;
|
||||
final MapCreatedCallback? onMapCreated;
|
||||
final bool myLocationEnabled;
|
||||
|
||||
const IntaleqMap({
|
||||
super.key,
|
||||
required this.apiKey,
|
||||
this.styleUrl,
|
||||
this.initialPosition = const LatLng(33.5138, 36.2765),
|
||||
this.initialZoom = 14.0,
|
||||
this.onMapCreated,
|
||||
this.myLocationEnabled = false,
|
||||
});
|
||||
|
||||
@override
|
||||
State<IntaleqMap> createState() => _IntaleqMapState();
|
||||
}
|
||||
|
||||
class _IntaleqMapState extends State<IntaleqMap> {
|
||||
IntaleqMapController? _intaleqController;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final style = widget.styleUrl ?? IntaleqStyles.obsidian(widget.apiKey);
|
||||
|
||||
return MaplibreMap(
|
||||
onMapCreated: (MaplibreMapController controller) {
|
||||
_intaleqController = IntaleqMapController(
|
||||
mapController: controller,
|
||||
apiKey: widget.apiKey,
|
||||
);
|
||||
if (widget.onMapCreated != null) {
|
||||
widget.onMapCreated!(_intaleqController!);
|
||||
}
|
||||
},
|
||||
styleString: style,
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: widget.initialPosition,
|
||||
zoom: widget.initialZoom,
|
||||
),
|
||||
myLocationEnabled: widget.myLocationEnabled,
|
||||
compassEnabled: false,
|
||||
trackCameraPosition: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import 'dart:ui';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart' as maplibre;
|
||||
import '../constants/colors.dart';
|
||||
|
||||
class MarkerOptions {
|
||||
final maplibre.LatLng position;
|
||||
final String? iconImage;
|
||||
final double? iconSize;
|
||||
final double? iconRotate;
|
||||
final String? textField;
|
||||
final double? textOffset;
|
||||
|
||||
MarkerOptions({
|
||||
required this.position,
|
||||
this.iconImage,
|
||||
this.iconSize,
|
||||
this.iconRotate,
|
||||
this.textField,
|
||||
this.textOffset,
|
||||
});
|
||||
|
||||
maplibre.SymbolOptions toSymbolOptions() {
|
||||
return maplibre.SymbolOptions(
|
||||
geometry: position,
|
||||
iconImage: iconImage,
|
||||
iconSize: iconSize,
|
||||
iconRotate: iconRotate,
|
||||
textField: textField,
|
||||
textOffset: textOffset != null ? Offset(0, textOffset!) : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PolylineOptions {
|
||||
final List<maplibre.LatLng> coordinates;
|
||||
final String? color;
|
||||
final double? width;
|
||||
final double? opacity;
|
||||
|
||||
PolylineOptions({
|
||||
required this.coordinates,
|
||||
this.color,
|
||||
this.width,
|
||||
this.opacity,
|
||||
});
|
||||
|
||||
maplibre.LineOptions toLineOptions() {
|
||||
return maplibre.LineOptions(
|
||||
geometry: coordinates,
|
||||
lineColor: color ?? IntaleqColors.primaryBlue,
|
||||
lineWidth: width ?? 5.0,
|
||||
lineOpacity: opacity ?? 1.0,
|
||||
lineJoin: 'round',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CircleOptions {
|
||||
final maplibre.LatLng position;
|
||||
final double radius;
|
||||
final String? color;
|
||||
final double? opacity;
|
||||
final String? strokeColor;
|
||||
final double? strokeWidth;
|
||||
|
||||
CircleOptions({
|
||||
required this.position,
|
||||
required this.radius,
|
||||
this.color,
|
||||
this.opacity,
|
||||
this.strokeColor,
|
||||
this.strokeWidth,
|
||||
});
|
||||
|
||||
maplibre.CircleOptions toMapLibreOptions() {
|
||||
return maplibre.CircleOptions(
|
||||
geometry: position,
|
||||
circleRadius: radius,
|
||||
circleColor: color ?? IntaleqColors.primaryBlue,
|
||||
circleOpacity: opacity ?? 0.6,
|
||||
circleStrokeColor: strokeColor,
|
||||
circleStrokeWidth: strokeWidth,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PolygonOptions {
|
||||
/// The list of rings. The first ring is the outer boundary,
|
||||
/// and subsequent rings are holes.
|
||||
final List<List<maplibre.LatLng>> rings;
|
||||
final String? fillColor;
|
||||
final double? fillOpacity;
|
||||
final String? outlineColor;
|
||||
|
||||
PolygonOptions({
|
||||
required this.rings,
|
||||
this.fillColor,
|
||||
this.fillOpacity,
|
||||
this.outlineColor,
|
||||
});
|
||||
|
||||
maplibre.FillOptions toFillOptions() {
|
||||
return maplibre.FillOptions(
|
||||
geometry: rings,
|
||||
fillColor: fillColor ?? IntaleqColors.fillGray,
|
||||
fillOpacity: fillOpacity ?? 0.4,
|
||||
fillOutlineColor: outlineColor ?? IntaleqColors.primaryBlue,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class IntaleqStyles {
|
||||
/// Dark premium map style (The default for Intaleq)
|
||||
static String obsidian(String apiKey) =>
|
||||
'https://maps.intaleq.com/styles/obsidian/style.json?key=$apiKey';
|
||||
|
||||
/// Light premium map style
|
||||
static String light(String apiKey) =>
|
||||
'https://maps.intaleq.com/styles/light/style.json?key=$apiKey';
|
||||
|
||||
/// Satellite hybrid style
|
||||
static String satellite(String apiKey) =>
|
||||
'https://maps.intaleq.com/styles/satellite/style.json?key=$apiKey';
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
|
||||
class PolylineUtils {
|
||||
/// Decode a Google-encoded polyline string into a list of LatLng coordinates.
|
||||
static List<LatLng> decode(String encoded) {
|
||||
List<LatLng> points = [];
|
||||
int index = 0, len = encoded.length;
|
||||
int lat = 0, lng = 0;
|
||||
|
||||
while (index < len) {
|
||||
int b, shift = 0, result = 0;
|
||||
do {
|
||||
b = encoded.codeUnitAt(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||
lat += dlat;
|
||||
|
||||
shift = 0;
|
||||
result = 0;
|
||||
do {
|
||||
b = encoded.codeUnitAt(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
|
||||
lng += dlng;
|
||||
|
||||
points.add(LatLng(lat / 1E5, lng / 1E5));
|
||||
}
|
||||
return points;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.9"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
geolocator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: geolocator
|
||||
sha256: f4efb8d3c4cdcad2e226af9661eb1a0dd38c71a9494b22526f9da80ab79520e5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.1.1"
|
||||
geolocator_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_android
|
||||
sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.6.2"
|
||||
geolocator_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_apple
|
||||
sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.13"
|
||||
geolocator_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_platform_interface
|
||||
sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.6"
|
||||
geolocator_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_web
|
||||
sha256: "102e7da05b48ca6bf0a5bda0010f886b171d1a08059f01bfe02addd0175ebece"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
geolocator_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_windows
|
||||
sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.5"
|
||||
get:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: get
|
||||
sha256: "5ed34a7925b85336e15d472cc4cfe7d9ebf4ab8e8b9f688585bf6b50f4c3d79a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.7.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.0"
|
||||
intl:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: intl
|
||||
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.20.2"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
latlong2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: latlong2
|
||||
sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.1"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: lints
|
||||
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
maplibre_gl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: maplibre_gl
|
||||
sha256: "9dd9eebee52f42a45aaa9cdb912afa47845c37007b26a799aa482ecd368804c8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.19.0+2"
|
||||
maplibre_gl_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: maplibre_gl_platform_interface
|
||||
sha256: a95fa38a3532253f32dfe181389adfe9f402773e58ac902d9c4efad3209e0903
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.19.0+2"
|
||||
maplibre_gl_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: maplibre_gl_web
|
||||
sha256: "7f1540b384f16f3c9bc8b4ebdfca96fb07f6dab5d9ef4dd0e102985dba238691"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.19.0+2"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.18"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.2"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
posix:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: posix
|
||||
sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.3"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.0.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.6.1"
|
||||
sdks:
|
||||
dart: ">=3.9.0-0 <4.0.0"
|
||||
flutter: ">=3.18.0-18.0.pre.54"
|
||||
@@ -1,7 +1,7 @@
|
||||
name: intaleq_maps
|
||||
description: Premium Flutter SDK for Intaleq Map Platform (Jordan & Syria).
|
||||
version: 1.0.0
|
||||
homepage: https://intaleq.com
|
||||
homepage: https://intaleqapp.com
|
||||
|
||||
environment:
|
||||
sdk: ">=3.0.0 <4.0.0"
|
||||
@@ -10,8 +10,14 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
maplibre_gl: ^0.19.0 # Use standard MapLibre plugin
|
||||
maplibre_gl: ^0.19.0
|
||||
http: ^1.1.0
|
||||
geolocator: ^10.1.0
|
||||
get: ^4.6.6
|
||||
latlong2: ^0.9.0
|
||||
|
||||
repository: https://github.com/Hamza-Ayed/intaleq_maps
|
||||
issue_tracker: https://github.com/Hamza-Ayed/intaleq_maps/issues
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
## 1.0.0
|
||||
|
||||
* Initial release of the Intaleq Maps JS SDK (`intaleq-maps-gl`).
|
||||
* Full feature parity with the Flutter SDK.
|
||||
* Friendly methods for Markers, Polylines, Polygons, and Circles.
|
||||
* Integrated search and routing API helpers.
|
||||
* Built-in Intaleq branding palette.
|
||||
* Built-in Polyline decoding utility.
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Intaleq
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Intaleq Maps JS SDK (`intaleq-maps-gl`)
|
||||
|
||||
A premium JavaScript/TypeScript SDK for the Intaleq Map Platform, built on top of MapLibre GL. Optimized for high-performance mapping in Jordan, Syria, and the broader region.
|
||||
|
||||
## Features
|
||||
|
||||
- **Simplified Geometry**: Use `addIntaleqMarker`, `addIntaleqPolyline`, `addIntaleqPolygon`, and `addIntaleqCircle` for rapid development.
|
||||
- **Intaleq Routing**: Integrated multi-profile routing API.
|
||||
- **Intaleq Geocoding**: High-performance place search and reverse geocoding.
|
||||
- **Branding-Ready**: Built-in Intaleq branding colors and premium map styles (Obsidian, Light, Satellite).
|
||||
- **Polyline decoding**: Built-in support for decoding server-side encoded routes.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install intaleq-maps-gl
|
||||
```
|
||||
|
||||
Or via CDN:
|
||||
|
||||
```html
|
||||
<script src="https://unpkg.com/intaleq-maps-gl/dist/index.js"></script>
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Initialize the Map
|
||||
|
||||
```javascript
|
||||
import { IntaleqMap } from 'intaleq-maps-gl';
|
||||
|
||||
const map = new IntaleqMap({
|
||||
container: 'map',
|
||||
apiKey: 'YOUR_INTALEQ_API_KEY',
|
||||
styleType: 'obsidian'
|
||||
});
|
||||
|
||||
map.on('load', () => {
|
||||
// Add a marker
|
||||
map.addIntaleqMarker({
|
||||
position: [36.2765, 33.5138], // [lng, lat]
|
||||
color: '#0D47A1'
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Search for Places
|
||||
|
||||
```javascript
|
||||
const results = await map.search('Amman');
|
||||
console.log(results);
|
||||
```
|
||||
|
||||
### Get a Route
|
||||
|
||||
```javascript
|
||||
const route = await map.getRoute([36.2, 33.5], [36.3, 33.6]);
|
||||
map.addIntaleqPolyline({
|
||||
id: 'route-line',
|
||||
coordinates: route.geometry.coordinates
|
||||
});
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
For full documentation and API reference, visit the [Intaleq Documentation](https://map-dashbord.intaleqapp.com/dashboard.html#docs).
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
@@ -0,0 +1,104 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Intaleq Maps JS SDK - Live Demo</title>
|
||||
<link href="https://unpkg.com/maplibre-gl@5.1.1/dist/maplibre-gl.css" rel="stylesheet" />
|
||||
<style>
|
||||
body { margin: 0; padding: 0; font-family: 'Inter', sans-serif; overflow: hidden; }
|
||||
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
padding: 20px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
backdrop-filter: blur(10px);
|
||||
z-index: 10;
|
||||
width: 300px;
|
||||
}
|
||||
h1 { margin: 0 0 10px; font-size: 18px; color: #0D47A1; }
|
||||
p { margin: 0 0 15px; font-size: 13px; color: #666; line-height: 1.5; }
|
||||
.btn {
|
||||
background: #0D47A1;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 15px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
width: 100%;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.btn:hover { background: #1565C0; transform: translateY(-1px); }
|
||||
.status { margin-top: 10px; font-size: 11px; color: #4CAF50; font-weight: 500; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="overlay">
|
||||
<h1>Intaleq SDK Demo</h1>
|
||||
<p>This demo showcases the <b>Intaleq Maps JS SDK</b> in action. It utilizes our premium Obsidian style and simplified geometry API.</p>
|
||||
<button class="btn" onclick="addDemoObjects()">Add Route & Marker</button>
|
||||
<div id="status" class="status"></div>
|
||||
</div>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
<!-- Since we haven't published to NPM yet, we reference the local source in this demo template -->
|
||||
<!-- In a real world production example, you would use: -->
|
||||
<!-- <script src="https://unpkg.com/intaleq-maps-gl/dist/index.js"></script> -->
|
||||
|
||||
<script type="module">
|
||||
// Mocking the IntaleqMap interface for this standalone demo
|
||||
// In production, this would be imported from the SDK
|
||||
import { IntaleqMap, PolylineUtils } from '../src/index.ts';
|
||||
|
||||
const apiKey = 'YOUR_INTALEQ_API_KEY'; // Replace with a valid key for live testing
|
||||
|
||||
const map = new IntaleqMap({
|
||||
container: 'map',
|
||||
apiKey: apiKey,
|
||||
styleType: 'obsidian',
|
||||
center: [36.2765, 33.5138], // Damascus
|
||||
zoom: 13
|
||||
});
|
||||
|
||||
window.addDemoObjects = async () => {
|
||||
document.getElementById('status').innerText = 'Adding Intaleq objects...';
|
||||
|
||||
// 1. Add a Marker
|
||||
map.addIntaleqMarker({
|
||||
position: [36.2765, 33.5138],
|
||||
color: '#0D47A1'
|
||||
});
|
||||
|
||||
// 2. Mock a route (in reality, you'd use map.getRoute())
|
||||
const mockCoordinates = [
|
||||
[36.2765, 33.5138],
|
||||
[36.28, 33.515],
|
||||
[36.285, 33.52],
|
||||
[36.29, 33.525]
|
||||
];
|
||||
|
||||
map.addIntaleqPolyline({
|
||||
id: 'demo-route',
|
||||
coordinates: mockCoordinates,
|
||||
width: 6,
|
||||
color: '#00e5ff'
|
||||
});
|
||||
|
||||
document.getElementById('status').innerText = 'Demo objects added successfully!';
|
||||
};
|
||||
|
||||
map.on('load', () => {
|
||||
console.log('Intaleq Map Loaded');
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,10 +1,15 @@
|
||||
{
|
||||
"name": "@intaleq/maps-gl",
|
||||
"name": "intaleq-maps-gl",
|
||||
"version": "1.0.0",
|
||||
"description": "Premium JavaScript SDK for Intaleq Map Platform",
|
||||
"description": "Premium JavaScript SDK for Intaleq Map Platform (Jordan & Syria)",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
"types": "dist/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Hamza-Ayed/intaleq_maps_gl_js.git"
|
||||
},
|
||||
"homepage": "https://intaleqapp.com",
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --format cjs,esm --dts",
|
||||
"dev": "tsup src/index.ts --format cjs,esm --watch --dts",
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Default Intaleq branding colors and stylings.
|
||||
*/
|
||||
export const IntaleqColors = {
|
||||
/** The signature Intaleq Blue color. */
|
||||
primaryBlue: '#0D47A1',
|
||||
|
||||
/** Cyan used for remaining route lines. */
|
||||
routeCyan: '#00e5ff',
|
||||
|
||||
/** Gray used for traveled paths or alternatives. */
|
||||
softGray: '#BDBDBD',
|
||||
|
||||
/** Semi-transparent gray for polygon fills. */
|
||||
fillGray: '#BDBDBD33', // 20% opacity
|
||||
|
||||
/** Red for error or stop states. */
|
||||
alertRed: '#ba1a1a',
|
||||
} as const;
|
||||
@@ -1,9 +1,41 @@
|
||||
import maplibregl from 'maplibre-gl';
|
||||
import { IntaleqColors } from './constants';
|
||||
import { PolylineUtils } from './utils';
|
||||
|
||||
export interface IntaleqMapOptions extends Omit<maplibregl.MapOptions, 'container'> {
|
||||
container: string | HTMLElement;
|
||||
apiKey: string;
|
||||
styleType?: 'obsidian' | 'light' | 'hybrid';
|
||||
styleType?: 'obsidian' | 'light' | 'hybrid' | 'satellite';
|
||||
}
|
||||
|
||||
export interface MarkerOptions extends maplibregl.MarkerOptions {
|
||||
position: [number, number];
|
||||
}
|
||||
|
||||
export interface PolylineOptions {
|
||||
id: string;
|
||||
coordinates: [number, number][];
|
||||
color?: string;
|
||||
width?: number;
|
||||
opacity?: number;
|
||||
}
|
||||
|
||||
export interface PolygonOptions {
|
||||
id: string;
|
||||
rings: [number, number][][]; // First is outer, others are holes
|
||||
fillColor?: string;
|
||||
fillOpacity?: number;
|
||||
outlineColor?: string;
|
||||
}
|
||||
|
||||
export interface CircleOptions {
|
||||
id: string;
|
||||
position: [number, number];
|
||||
radiusMetres: number;
|
||||
color?: string;
|
||||
opacity?: number;
|
||||
strokeColor?: string;
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -12,12 +44,11 @@ export interface IntaleqMapOptions extends Omit<maplibregl.MapOptions, 'containe
|
||||
*/
|
||||
export class IntaleqMap extends maplibregl.Map {
|
||||
private readonly intaleqApiKey: string;
|
||||
private addedIntaleqIds: Set<string> = new Set();
|
||||
|
||||
constructor(options: IntaleqMapOptions) {
|
||||
const { apiKey, styleType = 'obsidian', ...mapOptions } = options;
|
||||
|
||||
// Construct the Intaleq style URL
|
||||
// In production, this points to our tile server with the API key
|
||||
const styleUrl = `https://maps.intaleq.com/styles/${styleType}/style.json?key=${apiKey}`;
|
||||
|
||||
super({
|
||||
@@ -27,7 +58,6 @@ export class IntaleqMap extends maplibregl.Map {
|
||||
center: mapOptions.center ?? [35.9239, 31.9522], // Default to Amman
|
||||
zoom: mapOptions.zoom ?? 12,
|
||||
transformRequest: (url: string) => {
|
||||
// Automatically append API key to all tile and asset requests
|
||||
if (url.includes('intaleq.com')) {
|
||||
const separator = url.includes('?') ? '&' : '?';
|
||||
return {
|
||||
@@ -56,6 +86,134 @@ export class IntaleqMap extends maplibregl.Map {
|
||||
const response = await fetch(`https://map-saas.intaleq.com/v1/routing/route?start=${start.join(',')}&end=${end.join(',')}&profile=${profile}&key=${this.intaleqApiKey}`);
|
||||
return response.json();
|
||||
}
|
||||
|
||||
// --- Friendly Abstractions (Transformation Layer) ---
|
||||
|
||||
/**
|
||||
* Add a high-quality marker to the map (HTML-based).
|
||||
*/
|
||||
addIntaleqMarker(options: MarkerOptions): maplibregl.Marker {
|
||||
const marker = new maplibregl.Marker(options)
|
||||
.setLngLat(options.position)
|
||||
.addTo(this);
|
||||
return marker;
|
||||
}
|
||||
|
||||
export { maplibregl };
|
||||
/**
|
||||
* Add a polyline (route line) to the map.
|
||||
*/
|
||||
addIntaleqPolyline(options: PolylineOptions) {
|
||||
const { id, coordinates, color, width, opacity } = options;
|
||||
this.addSource(id, {
|
||||
type: 'geojson',
|
||||
data: {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'LineString',
|
||||
coordinates: coordinates
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.addLayer({
|
||||
id: id,
|
||||
type: 'line',
|
||||
source: id,
|
||||
layout: {
|
||||
'line-join': 'round',
|
||||
'line-cap': 'round'
|
||||
},
|
||||
paint: {
|
||||
'line-color': color ?? IntaleqColors.primaryBlue,
|
||||
'line-width': width ?? 5,
|
||||
'line-opacity': opacity ?? 1.0
|
||||
}
|
||||
});
|
||||
this.addedIntaleqIds.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a polygon (with hole support) to the map.
|
||||
*/
|
||||
addIntaleqPolygon(options: PolygonOptions) {
|
||||
const { id, rings, fillColor, fillOpacity, outlineColor } = options;
|
||||
this.addSource(id, {
|
||||
type: 'geojson',
|
||||
data: {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Polygon',
|
||||
coordinates: rings
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.addLayer({
|
||||
id: id,
|
||||
type: 'fill',
|
||||
source: id,
|
||||
paint: {
|
||||
'fill-color': fillColor ?? IntaleqColors.fillGray,
|
||||
'fill-opacity': fillOpacity ?? 0.4,
|
||||
'fill-outline-color': outlineColor ?? IntaleqColors.primaryBlue
|
||||
}
|
||||
});
|
||||
this.addedIntaleqIds.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a circle to the map.
|
||||
* Note: radius is in pixels for standard GL circles.
|
||||
* For geographic circles, consider using polygon buffers.
|
||||
*/
|
||||
addIntaleqCircle(options: CircleOptions) {
|
||||
const { id, position, radiusMetres, color, opacity, strokeColor, strokeWidth } = options;
|
||||
|
||||
this.addSource(id, {
|
||||
type: 'geojson',
|
||||
data: {
|
||||
type: 'Feature',
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: position
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.addLayer({
|
||||
id: id,
|
||||
type: 'circle',
|
||||
source: id,
|
||||
paint: {
|
||||
'circle-radius': radiusMetres / 10, // Rough pixel approximation for demo
|
||||
'circle-color': color ?? IntaleqColors.primaryBlue,
|
||||
'circle-opacity': opacity ?? 0.6,
|
||||
'circle-stroke-color': strokeColor ?? '#ffffff',
|
||||
'circle-stroke-width': strokeWidth ?? 2
|
||||
}
|
||||
});
|
||||
this.addedIntaleqIds.add(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an object added via Intaleq helpers.
|
||||
*/
|
||||
removeIntaleqObject(id: string) {
|
||||
if (this.getLayer(id)) this.removeLayer(id);
|
||||
if (this.getSource(id)) this.removeSource(id);
|
||||
this.addedIntaleqIds.delete(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all objects added via Intaleq helpers.
|
||||
*/
|
||||
clearAll() {
|
||||
this.addedIntaleqIds.forEach(id => this.removeIntaleqObject(id));
|
||||
this.addedIntaleqIds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export { maplibregl, IntaleqColors, PolylineUtils };
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Utilities for Intaleq Map SDK.
|
||||
*/
|
||||
export class PolylineUtils {
|
||||
/**
|
||||
* Decodes a Google-encoded polyline string into an array of [lng, lat] coordinates.
|
||||
* Note: MapLibre and GeoJSON use [lng, lat] while Google/Flutter use [lat, lng].
|
||||
*/
|
||||
static decode(encoded: string): [number, number][] {
|
||||
const points: [number, number][] = [];
|
||||
let index = 0;
|
||||
const len = encoded.length;
|
||||
let lat = 0;
|
||||
let lng = 0;
|
||||
|
||||
while (index < len) {
|
||||
let b: number;
|
||||
let shift = 0;
|
||||
let result = 0;
|
||||
do {
|
||||
b = encoded.charCodeAt(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
const dlat = ((result & 1) !== 0 ? ~(result >> 1) : (result >> 1));
|
||||
lat += dlat;
|
||||
|
||||
shift = 0;
|
||||
result = 0;
|
||||
do {
|
||||
b = encoded.charCodeAt(index++) - 63;
|
||||
result |= (b & 0x1f) << shift;
|
||||
shift += 5;
|
||||
} while (b >= 0x20);
|
||||
const dlng = ((result & 1) !== 0 ? ~(result >> 1) : (result >> 1));
|
||||
lng += dlng;
|
||||
|
||||
// MapLibre uses [lng, lat]
|
||||
points.push([lng / 1E5, lat / 1E5]);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user