LeafletForBlazor 2.0.0.4
See the version list below for details.
dotnet add package LeafletForBlazor --version 2.0.0.4
NuGet\Install-Package LeafletForBlazor -Version 2.0.0.4
<PackageReference Include="LeafletForBlazor" Version="2.0.0.4" />
paket add LeafletForBlazor --version 2.0.0.4
#r "nuget: LeafletForBlazor, 2.0.0.4"
// Install LeafletForBlazor as a Cake Addin #addin nuget:?package=LeafletForBlazor&version=2.0.0.4 // Install LeafletForBlazor as a Cake Tool #tool nuget:?package=LeafletForBlazor&version=2.0.0.4
Leaflet Map for Blazor
You can quickly add a map to the blazor page. Starting with version 2.0.0, LeafletForBlazor provide you a new control (RealTimeMap) for real time data displaying and analysis. Data can come from various (provided by various) tracking devices: router (static) and mobile phone, GPS of the fleet (dynamic) etc.
This package is under development, but I will keep the code compatible from one version to another.
You can find more information:
What's New?
Geometric class
Geometric is a new class that will provide functionalities for working with data.
This class will be a parent class (more precisely, host class - there is no inheritance) for the geometric shapes (ex. Points), geometric map shapes appearance, geometric analisys and so one supported by RealTimeMap.
Points class
The Points class is hosted by the Geometric class.
This class will work with RealTimeMap points. The points displayed in the map will be defined by the StreamPoint class, whose structure is predefined but which can be extended (value property is of type object).
Also, this class will provide methods to control the display of points (Appearance()), analysis (points collection) and so one.
StreamPoint
Class has the following structure:
public interface IStreamPoint
{
public Guid guid { get; set; } //globally unique identifier
public DateTime timestamp { get; set; } //Date and Time
public double latitude { get; set; } //EPSG latitude coordionate
public double longitude { get; set; } //EPSG longitude coordionate
public string type { get; set; } //StreamPoint type
public object value { get; set; } //StreamPoint value (object)
}
latitude and longitude properties are Web Mercator coordinate values.
The value property can be string or object defined by customn Data Structure Class.
Working with Points collection
The class provides the following methods:
Upload stream points
Geometric.Points.upload(StreamPoint[] points, bool newCollection = false);
Add single points
Geometric.Points.add(StreamPoint point);
Add more points
Geometric.Points.add(StreamPoint[] point);
Delete stream points
//delete all points from Geometric.Points collection Geometric.Points.delete(); //delete point, from Geometric.Points collection, with specified id (guid) Geometric.Points.delete(string id); //delete points, from Geometric.Points collection, with speciefied ids (guids) Geometric.Points.delete(string[] ids);
Move single point
//move single point from Geometric.Points collection Geometric.Points.moveTo(StreamPoint point);
Move more stream points
//move one ore more ponts from Geometric.Points collection Geometric.Points.moveTo(StreamPoint[] points);
Get all stream points
//return List<StreamPoint> from Geometric.Points Geometric.Points.getItems();
Get the points that match a criteria
//return IEnumerable<StreamPoint> from Geometric.Points Geometric.Points.getItems(item=>item.timestamp == DateTime.Now);
Change appearance of Map points collection
change the appearance of some of the points from collection
Geometric.Points.Appearance(item=>item.type == "type 1").pattern = new PointSymbol(){ radius = 18, color = "#28ffff", opacity = 0.68, fillColor = "blue", weight = 2, fillOpacity = 0.68 }
Code Example
Code example for Points collection.
Add in _Imports.razor project file
@using LeafletForBlazor
Blazor Page:
<RealTimeMap
width="600px"
height="600px"
@ref="realTimeMap"
></RealTimeMap>
Blazor code block:
Reference to RealTimeMap control (from Blazor Page):
@code {
RealTimeMap? realTimeMap; //reference to control
}
Stream points collection
List<RealTimeMap.StreamPoint> points = new List<RealTimeMap.StreamPoint> {
new RealTimeMap.StreamPoint()
{
guid = Guid.Parse("15366d7f-0689-4b8e-a2ee-29e5cb27f76e"),
latitude = 44.4502578,
longitude = 26.1108199,
type = "type 1",
value = "a point-specific value",
}
}
latitude and longitude properties are Web Mercator coordinate values.
In this previous, the value property is of string type
If the timestamp is missing, LeafletForBlazor will assign the current date
This collection has a static behavior.
Upload points collection
if(realTimeMap !=null)
await realTimeMap.Geometric.Points.upload(points, true);
where, the last parameter is newCollection:
if it's missing, it means it's false. That is, the previous collection is kept;
if(realTimeMap !=null) await realTimeMap.Geometric.Points.upload(points);
if it's true, a new collection will be created;
Add point(s) to Geometric.Points
Add single point to Geometric.Points
if (realTimeMap!=null)
await realTimeMap.Geometric.Points.add(point);
Add more points to Geometric.Points
if (realTimeMap!=null)
await realTimeMap.Geometric.Points.add(points.ToArray());
Delete
Delete all points from Geometric.Points:
if(realTimeMap!=null)
await realTimeMap.Geometric.Points.delete(); //delete all points from Geometric.Points
Delete single points from Geometric.Points:
if(realTimeMap!=null)
await realTimeMap.Geometric.Points.delete("15366d7f-0689-4b8e-a2ee-29e5cb27f76e"); //delete point by guid
Delete multiple points from Geometric.Points:
string[] ids = new string[2] { "15366d7f-0689-4b8e-a2ee-28e5cb22f26e",
"46246d6f-0684-4b8e-a2ee-26e2cb28f86f" };
if(realTimeMap!=null)
await realTimeMap.Geometric.Points.delete(ids); //delete points by guid
Moving points on the map
Moving single point from Geometric.Points
var point = new RealTimeMap.StreamPoint()
{
latitude = 44.4504845,
longitude = 26.1128922,
type = "type1",
value = "type 1",
guid = Guid.Parse("15366d7f-0689-4b8e-a2ee-29e5cb27f76e") //existing guide in the Geometric.Points collection
};
if (realTimeMap != null)
await realTimeMap.Geometric.Points.moveTo(point);
during the move you cannot change the attributes (type, value, timestamp)
Moving multiple points from Geometric.Points
var point = new RealTimeMap.StreamPoint()
{
latitude = 44.4504845,
longitude = 26.1128922,
type = "type1",
value = "type 1",
guid = Guid.Parse("15366d7f-0689-4b8e-a2ee-29e5cb27f76e") //existing guide in the Geometric.Points collection
};
var points = new List<RealTimeMap.StreamPoint>();
points.Add(point);
if (realTimeMap != null)
await realTimeMap.Geometric.Points.moveTo(points.ToArray());
during the move you cannot change the attributes (type, value, timestamp). A warning will appear in the console
Change appearance of the points collection
Change appearance of all points from points collection
realTimeMap.Geometric.Points.Appearance(item => true).pattern = new RealTimeMap.PointSymbol() {
radius = 8,
color = "gray",
opacity = 0.68,
fillColor = "gray",
weight = 4,
fillOpacity = 0.68
};
You can use predicate of Appearance method to filter points
realTimeMap.Geometric.Points.Appearance(item => item.type == "points of type 1").pattern = new RealTimeMap.PointSymbol() {
radius = 16,
color = "rgb(200,100,0)",
opacity = 0.68,
fillColor = "red",
weight = 4,
fillOpacity = 0.68
};
RealTimeMap Blazor control
This new control is optimized for working with streaming data.
Working with a single point (ex. my position)
A first method added to the control is movePoint(args...) which allows displaying the position of a single point. The method can be used to monitor one's own position.
The movePoint() method accepts from one argument to three arguments:
- coordinate (double[2]): point coordinate. For example: realTimeMap.movePoint([44.4502578, 26.1108199]). Latitude and Longitude in degrees, geographical coordinates;
- symbol (PointSymbol/PointIcon): the point can be displayed with a circle (PointSymbol) or an icon/*.png (PointIcon);
- tooltip (PointTooltip): configuring a tooltip with various information;
The blue print definitions of the classes used by the movePoint() method:
PointTooltip
public class PointTooltip
{
public string? content { get; set; } //accept html content
public bool permanent { get; set; } = true;
public double opacity { get; set; } = 0.9;
}
PointSymbol
public class PointSymbol
{
public int radius { get; set; } = 4;
public string? fillColor {get;set;}
public string? color {get;set;}
public int weight{get;set;}
public double opacity{get;set;}
public double fillOpacity { get; set; } = 1;
}
PointIcon
public class PointIcon
{
public string iconUrl{get; set;} //icon url (ex. *.png file)
public int[] iconSize{get; set;} //pixels
public int[] iconAnchor{get; set;}
public int[] popupAnchor{get; set;}
public string shadowUrl{get; set;}
public int[] shadowSize{get; set;}
public int[] shadowAnchor{get; set;}
}
Add in _Imports.razor project file
@using LeafletForBlazor
Blazor Page:
<button @onclick="onClickRun">Run</button> //launch moving points
<RealTimeMap
@ref="realTimeMap"
width="600px"
height="600px"
Parameters="@parameters"
></RealTimeMap>
Blazor code block:
@code {
RealTimeMap? realTimeMap; //reference to map control
RealTimeMap.LoadParameters parameters = new RealTimeMap.LoadParameters() //general map settings
{
zoom_level = 18,
location = new RealTimeMap.Location()
{
latitude = 44.4501715,
longitude = 26.1107672,
}
}
//points (coordonate) on the route. For simulation...
List<List<double>> coordinates = new List<List<double>>() {
new List<double>() { 44.4502578, 26.1108199 },
new List<double>() { 44.4500215, 26.1105407 },
new List<double>() { 44.4497369, 26.1093086 },
new List<double>() { 44.4496145 , 26.1088460 },
new List<double>() { 44.4491875, 26.1079328 }
};
RealTimeMap.PointSymbol symbol = new RealTimeMap.PointSymbol()
{
color = "red",
fillColor = "yellow",
radius = 10,
weight = 3,
opacity = 1,
fillOpacity = 1
};
bool run = false;
private async Task onClickRun() //Button onclick event
{
run = !run;
for(var i=0;i<1000;i++)
{
pas = i % coordinates.Count;
RealTimeMap.PointTooltip tooltip = new RealTimeMap.PointTooltip() {
content=$"{Math.Round( coordinates[pas][0],3)},{Math.Round( coordinates[pas][1],3)}",
opacity = 0.6
};
await realTimeMap.movePoint(coordinates[pas].ToArray(), symbol, tooltip);
await Task.Delay(1000);
if (run == false)
return;
}
}
}
RealTimeMap movePoint() method GitHub example code
Basic Map configuration
Add in _Imports.razor project file
@using LeafletForBlazor
Blazor Page:
<Map
width="600px"
height="600px"
Parameters="@parameters"
></Map>
Blazor code block:
@code {
//map initialization parameters
Map.LoadParameters parameters = new Map.LoadParameters()
{
location = new Map.Location()
{
longitude = 26.097133,
latitude = 44.446165
},
zoom_level = 12
};
}
Basic Map configuration - GitHub example code
Map scale
Blazor Page:
<Map
width="600px"
height="600px"
Parameters="@parameters"
></Map>
Blazor code block:
@code {
//map initialization parameters
Map.LoadParameters parameters = new Map.LoadParameters()
{
map_scale = new Map.MapScale()
{
has = true,
meters = true,
miles = false
}
};
}
Map Scale - GitHub example code
Basemaps
Now, you can define a base map list, from various sources (Open Street Map, Open Cycle Map and so one).
The user of the application, created by you, will be able to change the basemap.
Blazor page:
<Map
width="800px"
height="700px"
Parameters="@parameters"
></Map>
Blazor code block
Map.LoadParameters parameters = new Map.LoadParameters()
{
....
basemap_layers = new List<Map.BasemapConfigLayer>
{
new Map.BasemapConfigLayer()
{
url = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution = "�Open Street Map",
title = "Open Street Map",
detect_retina = true
},
new Map.BasemapConfigLayer()
{
url = "https://tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=[your API Key]",
attribution = "�Open Cycle Map",
title = "Open Cycle Map"
}
}
};
Map Events
Click on Map method trigger:
onMapClick return Map.CurrentMapState object
Double Click on Map method trigger:
onMapDblClick return Map.CurrentMapState object
Recomandation! Use doubleClickZoom = false to disable zoom on double click, as can be seen below (below is an example).
Code Block:
Map.MapOptions map_options = new Map.MapOptions()
{
interaction_options = new Map.InteractionOptions()
{
doubleClickZoom = false
}
};
Blazor page:
<Map
width="800px"
height="600px"
Parameters="@parameters"
Options="@map_options"
onMapDblClick="@OnMapDoubleClick"
></Map>
Load Map method trigger:
onLoadMap return Map.CurrentMapState object
Working onLoadMap event - GitHub example code
Zoom on Map method trigger:
onZoomChange return Map.CurrentMapState object
Pan or Zoom on Map method trigger:
onMoveChange return Map.CurrentMapState object
Events parameter (blue print) of all methods trigger:
#region CurrentMapState and Location blue print
public class CurrentMapState //current state (bound, center and zoom level) of the Map
{
public Location location { get; set; } = new Location();
public int zoom_level { get; set; }
public MapBounds map_bounds { get; set; } = new MapBounds();
}
public class MapBounds //Map bound coordinates
{
public Location _southWest { get; set; } = new Location();
public Location _northEast { get; set; } = new Location();
}
public class Location //center Map location
{
public double longitude { get; set; }
public double latitude { get; set; }
}
#endregion
Map event example code
Below will be presented a simple example with the Double Click on Map event
Blazor Page:
<Map
width="800px"
height="600px"
Parameters="@parameters"
Options="@map_options"
onMapDblClick="@OnMapDblClick"
></Map>
Blazor code block:
@code{
public void OnMapDblClick(Map.CurrentMapState evt_parameters)
{
}
Map.MapOptions map_options = new Map.MapOptions()
{
interaction_options = new Map.InteractionOptions()
{
doubleClickZoom = false //here we will disable navigation in the map on double click. Is not mandatory!
}
};
Map.LoadParameters parameters = new Map.LoadParameters()
{
location = new Map.Location()
{
longitude = 26.1107672,
latitude = 44.4501715
},
zoom_level = 14
};
}
JSON file example (GeoJSON_urls Map parameter)
Blazor Page:
<Map
width="600px"
height="600px"
GeoJSON_urls="@urls.ToArray()"
></Map>
Blazor Code:
@code {
//working with GEOJson file
/*
GeoJSON_urls <Map> parameter expects an array of JSON url
1. The JSON data complies with the Leaflet documentation
2. A improved format that allows custom symbolization
3. The simultaneous use of the two types of format (RFC 7946 format and improved format)
*/
List<string> urls = new List<string>() {
"http://localhost:5078/polygonsfile.json",
"http://localhost:5078/pointsfile.json"
};
}
1. Leaflet documentation format
Is the format shown in the Leaflet documentation
GeoJSON specification (RFC 7946)
[ { "type": "Feature", "geometry": { "type": "Polygon", "coordinates": [ [ [ 26.0931846, 44.4432512 ], [ 26.0945783, 44.4435381 ], [ 26.0959206, 44.4438006 ], ... ] ] } ]
2. Improved Leaflet Format. This format allows configuring the symbolization of map elements
Is an leaflet format in which symbolization (with scaling) and tooltip configuration (with scaling) has been added to the leaflet data (RFC 7946).
Advantages
The symbology and tooltips configuration are stored along with the data;
Changing the symbolization will be done without changing the code;
Also, changing tooltips configuration will be done without changing the code;
Several applications (web, mobile, etc.) will display the same map, the same symbols;
{ "data": [...GeoJSON specification (RFC 7946)...], "symbology": { ... }, "tooltip": { ... } }
Meaning of JSON (improved format) parameters:
JSON "data" paratemeter expects an array of GeoJSON items GeoJSON specification (RFC 7946)
JSON "symbology" parameter expects the custom symbology of GeoJSON items
"symbology": { "default": { "color": "red", "weight": 5, "opacity": 0.4 }, "case": { "field_name": "name", "classes": [ { "value": "Bdul Magheru", "symbol": { "color": "yellow", "weight": 5, "opacity": 0.4 } }, { "value": "Bdul Dacia", "symbol": { "color": "green", "weight": 5, "opacity": 0.4 } } ] } "scaling": { "start_with": 16, "stop_with": 18 } }
In the previous example, we have a default symbol and two other symbols for two predefined classes. This two classes are defined based on the values in the "name" field.
Result of polygons classes symbolization of GitHub example:
Symbolization by classes is done based on a property (field) of the GeoJSON elements.
for example:
- commercial areas were symbolized in yellow;
- residential areas were symbolized in green;
- other areas were symbolized in red;
Working with JSON file - GitHub example code
Symbology and tooltip scaling
Map elements (with symbology) and tooltips will be displayed in the map only for zoom levels between start_with and stop_with.
In the case of the GeoJSON layer, scaling will only work when we have defined at least one default symbol
JSON "symbology" parameter expects the definition of GeoJSON items tooltip. "scaling" parameter is not mandatory.
"symbology": { "default": { "color": "red", "weight": 5, "opacity": 0.4 }, "scaling": { "start_with": 15, "stop_with": 18 } }
JSON "tooltip" parameter expects the definition of GeoJSON items tooltip. "scaling" parameter is not mandatory.
"tooltip": { "fields_name": [ "name", "lanes" ], "offset": [ 0, 0 ], "permanent": true, "opacity": 0.5, "coordinate_inversion": true, "scaling": { "start_with": 16, "stop_with": 18 } }
GeoJSON files and working with Layers Control
The Load Map boolean parmeter (anyway_overlay_layers_control) forces the display of GeoJSON layers in the Layers Control.
Map.LoadParameters parameters = new Map.LoadParameters()
{
anyway_overlay_layers_control = true
}
The names of the files will be displayed in the Layers Control, the overlay layers section.
Working with GeoJSON string array
GeoJSON data can be loaded as strings.
Add in your Blazor Page:
<Map
width="800px"
height="600px"
Parameters="@parameters"
GeoJSON_strings="@date_geojson.ToArray()"
></Map>
Blazor code block:
List<string> date_geojson = new List<string>()
{
"[{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[26.097369,44.444941]},\"properties\":{\"name\":\"Beautiful Memories Store\"}}]"
};
... and optional parameters:
Map.LoadParameters parameters = new Map.LoadParameters()
{
location = new Map.Location()
{
longitude = 26.1107672,
latitude = 44.4501715
},
zoom_level = 14,
map_scale = new Map.MapScale()
{
has = false,
meters = true
}
};
Images Overlay
Load and display images over specific bounds of the map.
Blazor Page:
<Map
width="750px"
height="650px"
MapOverlays="@overlays"
></Map>
Blazor code block:
@code{
Map.Overlays overlays = new Map.Overlays()
{
images = new Map.ImageOverlay()
{
images_and_bounds = new List<Map.ImagesAndBoundsCoordinates>()
{
new Map.ImagesAndBoundsCoordinates()
{
url = "http://localhost:5116/atene.png",
map_bounds = new Map.MapBounds()
{
_southWest = new Map.Location()
{
longitude = 26.0970904,
latitude=44.4409802
},
_northEast = new Map.Location()
{
longitude = 26.0985575,
latitude=44.4418393
}
}
},
new Map.ImagesAndBoundsCoordinates()
{
url = "http://localhost:5116/romana.png",
map_bounds = new Map.MapBounds()
{
_southWest = new Map.Location()
{
longitude = 26.0964848,
latitude=44.4465985
},
_northEast = new Map.Location()
{
longitude = 26.0983148,
latitude=44.4475250
}
}
}
}
}
};
}
Image overlay - GitHub example code
Working with Leaflet Plungins
Starting with 1.1.8 version, LeafletForBlazor NuGet is able to implement Leaflet plugins. These plugins will be adapted for use in Blazor.
Configuring the Geolet plugin
The configuration parameters have the same names as those in the Leaflet documentation:
Blazor page
<Map
width="800px"
height="700px"
Plugins="@plugins"
></Map>
Blazor code block
Map.PluginsConfig plugins = new Map.PluginsConfig()
{
display_all = true,
plugins = new List<Map.Plugin>() {
new Map.Plugin() {
name = "Geolet",
config = "{\"title\": \"Locatia mea\", \"position\": \"topleft\", \"popupContent\": \"`latitudine ${latlng.lat}<br>longitudine ${latlng.lng}`\"}"
}
}
};
The "config" parameter is a string json object.
Using Esri plugins
Esri is the most important player of the GIS market. Esri software solutions are complete and guarantee high performance. In addition, Esri offers users many open and/or freely used software solutions. You can freely use the power of Esri tools, only on the basis of an Esri API Key code
Extending the Leaflet API with Esri Basemaps plugin
Adding Esri basemaps is done on the PluginsConfig interface and the Plugins parameter of the LeafletForBlazor package.
First of all, you will need an Esri API Key code. Generating an Esri API Key code is free, but you need an Esri developer account.
Here you will find a guide for generating an Esri API Key code
Add in your Blazor Page:
<Map
width="800px"
height="700px"
Plugins="@plugins"
></Map>
Blazor code block:
@code{
Map.PluginsConfig plugins = new Map.PluginsConfig()
{
display_all = true,
plugins = new List<Map.Plugin>()
{
new Map.Plugin()
{
name = "Esri",
config = new Map.EsriPlugin()
{
apiKey = "[your Esri API Key code]",
esri_plugins_config = new List<object>()
{
new Map.EsriBasemapConfig()
{
enable = true,
esri_basemap_layers = new List<Map.EsriBasemapLayer>()
{
new Map.EsriBasemapLayer(){basemap_id ="ArcGIS:Imagery"},
new Map.EsriBasemapLayer(){basemap_id = "ArcGIS:Imagery:Standard"},
new Map.EsriBasemapLayer(){basemap_id = "ArcGIS:Imagery:Labels"}
}
}
}
}
}
}
};
};
Esri Basemap - GitHub example code
Extending the Leaflet API with Esri Geocoding Search plugin
First of all, you will need an Esri API Key code. Generating an Esri API Key code is free, but you need an Esri developer account.
Here you will find a guide for generating an Esri API Key code
Add in your Blazor Page:
<Map
width="800px"
height="800px"
Plugins="@plugins"
></Map>
Blazor code block:
Map.PluginsConfig plugins = new Map.PluginsConfig()
{
display_all = true,
plugins = new List<Map.Plugin>() {
new Map.Plugin()
{
name = "Esri",
config = new Map.EsriPlugin()
{
apiKey = "[your Esri API Key code]",
esri_plugins_config = new List<object>()
{
new Map.EsriGeocodingSearchParameters()
{
enable = true,
placeholder = "Your address",
position = "topleft",
nearby = new Map.EsriNearby(){lat = 0,lng = 0}
}
}
}
}
}
};
Esri Geocoding Search - GitHub example code
Extending the Leaflet API with Esri Reverse Geocoding plugin
First of all, you will need an Esri API Key code. Generating an Esri API Key code is free, but you need an Esri developer account.
Here you will find a guide for generating an Esri API Key code
Add in your Blazor Page:
<Map
width="800px"
height="800px"
Plugins="@plugins"
></Map>
Blazor code block:
Map.PluginsConfig plugins = new Map.PluginsConfig()
{
display_all = true,
plugins = new List<Map.Plugin>()
{
new Map.Plugin()
{
name = "Esri",
config = new Map.EsriPlugin()
{
apiKey = "[your Esri API Key code]",
esri_plugins_config = new List<object>()
{
new Map.EsriReverseGeocodingParameters()
{
enable = true,
remove_last_result = true
}
}
}
}
}
};
Reverse Geocoding - GitHub example code
O-L I
Thank you for choosing this package!
Laurentiu Ichim
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net7.0
- Microsoft.AspNetCore.Components.Web (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated | |
---|---|---|---|
2.2.2.2 | 165 | 11/4/2024 | |
2.2.2 | 246 | 10/31/2024 | |
2.2.0.4 | 1,045 | 9/22/2024 | |
2.2.0.2 | 240 | 9/17/2024 | |
2.2.0 | 603 | 8/28/2024 | |
2.0.8.8 | 495 | 8/15/2024 | |
2.0.8.6 | 592 | 7/31/2024 | |
2.0.8.2 | 386 | 7/24/2024 | |
2.0.6.8 | 1,354 | 6/7/2024 | |
2.0.6.4 | 466 | 5/29/2024 | |
2.0.6.2 | 122 | 5/28/2024 | |
2.0.4.8 | 212 | 5/23/2024 | |
2.0.4.6 | 1,948 | 4/18/2024 | |
2.0.4.4 | 740 | 3/27/2024 | |
2.0.4.2 | 218 | 3/22/2024 | |
2.0.2.8 | 1,401 | 3/3/2024 | |
2.0.2.6 | 466 | 2/28/2024 | |
2.0.2.4 | 573 | 2/19/2024 | |
2.0.2.2 | 1,372 | 1/24/2024 | |
2.0.0.8 | 437 | 1/18/2024 | |
2.0.0.6 | 1,119 | 12/25/2023 | |
2.0.0.4 | 1,132 | 12/6/2023 | |
1.2.4 | 1,438 | 4/7/2023 | |
1.2.3 | 792 | 4/4/2023 | |
1.2.2 | 840 | 3/27/2023 | |
1.2.1 | 803 | 3/12/2023 | |
1.2.0 | 781 | 3/11/2023 | |
1.1.9 | 763 | 3/9/2023 | |
1.1.8 | 777 | 3/8/2023 | |
1.1.5 | 998 | 3/2/2023 | |
1.1.4 | 726 | 2/28/2023 | |
1.1.2 | 786 | 2/25/2023 | |
1.1.1 | 699 | 2/24/2023 | |
1.1.0 | 726 | 2/23/2023 | |
1.0.9 | 845 | 2/23/2023 | |
1.0.8 | 728 | 2/22/2023 | |
1.0.6 | 972 | 2/18/2023 | |
1.0.5 | 834 | 2/17/2023 | |
1.0.4 | 924 | 2/14/2023 | |
1.0.3 | 744 | 2/14/2023 | |
1.0.2 | 751 | 2/14/2023 | |
1.0.1 | 742 | 2/13/2023 | |
1.0.0 | 772 | 2/13/2023 |
2023 12 06: Add StreamPoint defintion
2023 12 06: Add Geometric class - working with real time data (RealTimeMap control)
2023 12 06: Add Points class working with StreamPoint: update(), add(), moveTo(), delete(), getItems()
2023 12 06: Add Appearance() method to change appearance of the RealTimeMap point
Next: Nearby points Analisys