Skip to content

Changelog

15.0

15.0.1

Release date: 11/13/2026

ThinkGeo 15.0.1 is a maintenance release. No public API was removed or changed. It fixes the native libraries of ThinkGeo.Gdal, ThinkGeo.Cad, ThinkGeo.FileGeoDatabase, ThinkGeo.Oracle and ThinkGeo.NauticalCharts on Windows machines without the Visual C++ Redistributable, adds ThinkGeo.Cad on Linux x64, and fixes a set of drawing, printing and licensing issues.

ThinkGeo.Core Namespace:

New Features & Improvements

  • Improved labels of style.json maps that mix scripts: each character is drawn from the first font of the layer's text-font list that has it, so "Hong Kong 香港" keeps its Latin letters in the Latin font. Characters that no font of the list has come from the built-in Noto Sans, then a system font.
  • Added style.json glyphs given as a file: URL or a local path, absolute or relative to the style file (or to the application folder for a style built in code), so an offline style can ship its glyph files beside it.
  • Reduced the size of applications: SkiaSharp's debug symbols (libSkiaSharp.pdb, 80 to 95 MB per architecture) are no longer copied into the build output.

Licensing

  • A license key for another product family, such as a Web key in a WPF project, no longer fails the build: the families it does not cover build on the 30-day trial, and TG0001 names their packages.
  • A key file that cannot be read no longer fails the build: it is skipped, and TG0001 or TG0002 names it.
  • A THINKGEO_LICENSE that cannot be read (not a key, a path that does not exist, a file without a key, or a damaged key line) now fails the build with TG0004 even when another key is found, so a build server never falls back to the trial unnoticed.
  • The build check now recognizes a ThinkGeo UI assembly by the product it declares, not by its file name.
  • See the License Guide for ThinkGeo 15 for the build messages.

Bug Fixes

  • Fixed style.json vector tiles occasionally drawing a blank tile when the style also has raster or hillshade (raster-dem) sources and several tiles are fetched at the same time.
  • Fixed MapStyle.AddStyle(styleJson, source) with a style document that declares no sources reading every layer from a source named features: a document for an MBTiles, PMTiles or TgTiles archive drew nothing or did not open, and two archives could not be added to one style.
  • Fixed a polygon outline drawn by a style.json line layer missing a segment where a straight edge of the polygon runs close to a tile edge.
  • Fixed a MapPrinterLayoutAsyncLayer drawn in part on screen stretching that part over the whole frame on the next draw, failing a draw when its layers were refilled or its cached image cleared on the UI thread meanwhile, and losing its labels when drawn zoomed in and then in full; its layers now also get the canvas's cancellation token.
  • Fixed ScaleBarPrinterLayoutAsyncLayer with a dynamic bounding box throwing when zoomed in so far that no tick fits, which drew an error tile in place of the page in the print preview, and a scale bar drawn on two canvases at once taking one draw's position and zoom for the other.

ThinkGeo.Gdal:

  • Fixed GDAL failing to load (error 126) on Windows without the Visual C++ Redistributable when the application is built or published for a runtime identifier, such as -r win-x64.
  • Fixed .NET Framework applications built for Any CPU failing to load GDAL on Windows without the Visual C++ Redistributable: they received the 32-bit Visual C++ runtime but run as 64-bit (ThinkGeo.Dependency.MicrosoftVisualCRunTime140 15.0.2).
  • Improved ThinkGeo.Gdal.Dependency.Windows 15.0.1 to copy only the native files of the runtime a build targets.

ThinkGeo.FileGeoDatabase:

  • Changed File Geodatabase sources to throw PlatformNotSupportedException on platforms other than Windows x64, the only platform Esri's File Geodatabase API ships for, instead of BadImageFormatException.
  • Fixed .NET Framework applications built for Any CPU failing to open a geodatabase on Windows without the Visual C++ Redistributable.

ThinkGeo.Cad:

  • Added Linux x64 support: reference ThinkGeo.Cad.Dependency.Linux to read DWG and DXF drawings on Linux. On Windows the native files come from ThinkGeo.Cad.Dependency.Windows, which ThinkGeo.Cad references.
  • Changed DWG and DXF text to be converted to shapes through SkiaSharp instead of WPF, so ThinkGeo.Cad no longer needs WPF.
  • Fixed reading drawings on Windows without the Visual C++ Redistributable when the application is built for a runtime identifier, or is a .NET Framework application built for Any CPU.
  • Fixed reading a drawing printing ODA's loading progress to standard output.

ThinkGeo.Oracle:

  • Changed ThinkGeo.Oracle to target .NET Framework 4.6.2 and .NET 8 instead of .NET Standard 2.1, like the ThinkGeo.Gdal it builds on.
  • Changed OracleFeatureSource to throw PlatformNotSupportedException when opened on platforms other than Windows x64, instead of failing to connect without a reason.
  • Fixed .NET Framework applications built for Any CPU failing to connect on Windows without the Visual C++ Redistributable.

ThinkGeo.NauticalCharts:

  • Changed ThinkGeo.NauticalCharts to target .NET Framework 4.6.2 and .NET 8 instead of .NET Standard 2.1, like the ThinkGeo.Gdal it builds on.
  • Fixed .NET Framework applications built for Any CPU that reference only ThinkGeo.NauticalCharts failing on Windows without the Visual C++ Redistributable.

ThinkGeo.UI.Blazor Namespace:

New Features & Improvements

  • Added WmtsTileOverlay imagery over terrain on the MapLibre renderer: Web Mercator WMTS grids, including local origins and custom matrix identifiers, are resampled into XYZ tiles with their request parameters and headers kept.
  • Added the marker features of the OpenLayers renderer to the MapLibre renderer: CompositeMarkerStyle, RadialGradientMarkerStyle, PointMarkerStyle.AnimationFrames, Marker.HoverStyle and SelectionStyle, Ctrl-click and box selection, and Alt-drag rotation with MapView.EnableAltDragRotation.

Bug Fixes

  • Fixed a map coming up blank after an upgrade in a browser that had cached the previous release's scripts: the ThinkGeo client scripts, styles and images are now requested with the release's version.

15.0.0

Release date: 11/08/2026

ThinkGeo 15 is a major release. The Blazor map gains a MapLibre GL JS 6 renderer with tilt, rotation, 3D terrain and buildings and a globe view, and its VectorTileOverlay draws style.json and MapStyle styles over your own feature sources, with clustering, heatmaps, isolines and particle flow. Every platform gets offline PMTiles, the newer ThinkGeo Cloud vector tiles, asynchronous WFS, OGC API and ArcGIS feature sources, page-layout printing with vector PDF output and a new developer licensing model. Read Upgrading from ThinkGeo 14 at the end of this section before upgrading.

ThinkGeo.Core Namespace:

New Features & Improvements

Offline vector tiles

  • Added VectorPmTilesAsyncLayer and RasterPmTilesAsyncLayer for PMTiles v3 archives, vector tiles styled with a style.json or raster image tiles, and PmTilesHeader for an archive's tile type, zoom range, bounds and center.
  • Added VectorMbTilesGenerator and VectorPmTilesGenerator (GenerateMbTilesAsync, GeneratePmTilesAsync, EstimateTotalTiles) to build vector tile archives from any FeatureSource up to zoom 26 or 30, and FeatureSourceVectorTileCutter for single MVT tiles.

Vector tiles styled with style.json

  • Rebuilt style.json support in MvtTilesAsyncLayer, VectorMbTilesAsyncLayer and VectorPmTilesAsyncLayer on a new engine that follows MapLibre, .NET Framework included: expressions, filters, zoom interpolation, circle layers and fill patterns.
  • Improved label placement in these layers to match MapLibre: street names follow curved roads, shield numbers stay upright, icon-text-fit and upright CJK text are supported, and labels at tile edges are no longer cut (unrotated Web Mercator maps).
  • Improved PDF output of style.json vector tile layers: roads and areas are drawn as vector shapes instead of tile images, also inside a MapPrinterLayoutAsyncLayer, and straight line labels stay searchable text.
  • Changed MvtTilesAsyncLayer to raise its MaxDataZoom to the maxzoom the source's TileJSON publishes, so sources with tiles past zoom 14 (for example Mapbox at zoom 16) show their full detail.

ThinkGeo Cloud

  • Added ThinkGeoVectorTileAsyncLayer for the newer ThinkGeo Cloud vector tiles (API key, StyleUri such as ThinkGeoVectorStyles.Light), with VectorTileCache, LabelDisplayMode, TransparentBackground, WebProxy, TimeoutInSeconds and HTTP events.
  • Moved GeocodingCloudClient to the v3 geocoding service and ReverseGeocodingCloudClient to the v2 reverse geocoding service, with DataSources, LocationTypes, and Description, Location, IntersectingRoads and Priority on results.

Printing and PDF

  • Added page-layout printing to ThinkGeo.Core: PagePrinterLayoutAsyncLayer, MapPrinterLayoutAsyncLayer, LabelPrinterLayoutAsyncLayer, ImagePrinterLayoutAsyncLayer and LegendPrinterLayoutAsyncLayer, asynchronous and free of GDI+.
  • Added ScaleBarPrinterLayoutAsyncLayer, ScaleLinePrinterLayoutAsyncLayer, ScaleTextPrinterLayoutAsyncLayer, DataGridPrinterLayoutAsyncLayer and MagneticDeclinationPrinterLayoutAsyncLayer to the page-layout family (PrinterLayoutAsyncLayer).
  • Added PdfGeoCanvas for vector PDF export without a print driver on Windows, Linux and macOS: shapes stay vector, text stays searchable with its font embedded, and images keep full resolution. SetPageSize sizes the page.
  • Added PrinterLayoutDocument and PrinterLayoutPage for multi-page layouts: ExportPdfAsync writes every page into one PDF, each at its own sheet size, and DrawAsync draws a one-page layout on any canvas, such as a printer.
  • Improved page layouts to print at the physical size you set, so preview, PDF and paper match at any Dpi and display scaling, and added MapPrinterLayoutAsyncLayer.DrawingMode and PreviewDrawingMode (vector print, cached preview).
  • Added DataGridPrinterLayoutAsyncLayer.RowsPerPage and SplitIntoPages(), so a long attribute table runs onto following pages with its header repeated and its columns aligned from page to page.
  • Added the ISO page sizes A0 to A5 to PrinterPageSize, also for the classic PagePrinterLayer, and PrinterLayoutHelper (ConvertLength, GetPointsPerGeographyUnit) for custom layout layers, replacing PrinterHelper.

Online feature services (WFS, OGC API - Features, ArcGIS Server REST)

  • Added AsyncFeatureSource and AsyncFeatureLayer (GetFeaturesIntersectingAsync, GetFeaturesNearestToAsync and more); the WFS, OGC API and ArcGIS REST async layers expose theirs as FeatureSource, and the layer's SendingHttpRequest sees its requests.
  • Added WfsAsyncLayer/WfsAsyncFeatureSource for WFS 1.x (GeometryType from the schema, GetCapabilitiesAsync, GetLayersAsync) and OgcApiAsyncLayer/OgcApiAsyncFeatureSource for OGC API - Features (CollectionIds, BulkSize, GetFeaturesPageAsync).
  • Added Crs (server-side reprojection), GeometryType, WfsV2AsyncFeatureSource, and GetCapabilitiesAsync and GetLayersAsync with proxy and cancellation to WfsV2AsyncLayer; WfsV2FeatureSource and WfsV2FeatureLayer gained Crs and GeometryType.
  • Added Resolve and ResolveDepth to WfsV2AsyncFeatureSource to have the service resolve references, GetFeaturesPageAsync returning a FeaturePage, and ReadUntilEmptyPage for services that send short pages.
  • Added WfsV2CompositeAsyncLayer and WfsV2CompositeAsyncFeatureSource for WFS 2.0 feature types whose geometry lives in referenced features (for example ATKIS roads), joined as WfsComponentRelation describes.
  • Added ArcGisServerRestVectorAsyncFeatureSource with OutFields, OutSR, MaxAllowableOffset, GeometryPrecision and paging limits; ArcGisServerRestVectorAsyncLayer.MaxConcurrentRequests replaces MaxParallelRequests.

Online raster services

  • Added GoogleMapTilesAsyncLayer for the Google Maps Platform Map Tiles API (roadmap, satellite, terrain, hybrid), with session handling, attribution, language, region, and traffic and Street View layers.
  • Added WmsAsyncLayer.DrawingMarginInPixel (50 by default) so symbols and labels at tile edges are no longer cut, and made WmsClient and WmtsClient public to read a server's layers, styles, formats and coordinate systems.
  • Added WebBasedAsyncLayer.HttpMessageHandler, RasterXyzTileAsyncLayer.GetTileContentAsync, AzureMapsRasterAsyncLayer.GetAttributionAsync with cancellation and ArcGisServerRestLayerImageFormat.Png32; rejected requests now show the server's reason.

Grids, heatmaps and graticules

  • Added GridRasterLayer, which draws a GridSource (AscGridSource for ASCII grid files, InMemoryGridSource for your own values) as a colored raster through a GridFillStyle with gradient or class color stops.
  • Added HeatmapStyle, the same Gaussian heatmap as MapLibre GL, with Radius, RadiusUnit (pixels or ground distance), Weight, WeightColumnName, Intensity, Opacity and ColorStops; it replaces HeatStyle.
  • Added GraticuleAdornmentLayer for latitude and longitude lines with edge labels, replacing GraticuleFeatureLayer, and AdornmentLayer.UpdateWhileTransforming so adornments can redraw while the map zooms and rotates.

Raster files and tile caches

  • Improved GeoTIFF reading: overviews (pyramids) are used when zoomed out, a strip-organized image is decoded once instead of once per tile, and tiled files with non-square internal tiles no longer draw with a transparent bottom.
  • Added RasterImageCache to share decoded raster images across layers within a memory budget (MaximumBytes), and zoomed-out JPEG and GIF images are decoded at reduced size; drawing a raster with Opacity below 1 is faster.
  • Added WebP: SkiaRasterLayer draws WebP files and GeoImageFormat.Webp saves images and file tile caches as lossy WebP. Raster layers without a world file now read a GDAL .aux.xml file (WorldFile.TryLoadFromAuxXml).
  • Improved LayerBase.GenerateTileCacheAsync to draw tiles in parallel, with an overload that builds a layer set per worker, and added TileCache.GetLastUpdatedTimeUtcAsync, TileCache.DrainAsync and FileTileCache.DeleteTiles.

Projections

  • Added ProjectionConverter.DecimalDegreesToSphericalMercator (always open), TryConvertToExternalProjection and TryConvertToInternalProjection; converting no longer checks for a missing grid file per feature, and WKT input gets a clear error.
  • Added TileMatrixSet.Projection and TileMatrixSet.CreateTileMatrixSet(tileSize, boundingBox, projection, ...) to build a tile grid in any projection.

Geometry, Z values and the dateline

  • Added Z values: PointShape.HasZ, ZValues, SetZ and SetZValues on LineShape and RingShape, Z-aware WKB and WKT (WkbShapeType.PointZ and others), Z shapefiles and 3D GDAL sources. See ThinkGeoSettings.PreserveZ under Upgrading.
  • Added DatelineHelper (Split, Merge, IsSplit) to split geometry at the dateline and join it back, in any unit, and LineBaseShape.GetLineOnALine overloads that measure distances on the ground through a Projection.
  • Improved dateline handling: with WrapDateline, a feature layer draws geometry stored past +/-180 whole and without a seam line, and PointShape.TranslateByDegree and TranslateByOffset wrap the longitude instead of throwing.

Feature sources and layers

  • Added GeoJsonFeatureSource for GeoJSON files or text (FromGeoJson), and FeatureIdColumn on ShapeFileFeatureLayer, ShapeFileFeatureSource, TabFeatureLayer and TabFeatureSource to take stable feature ids from a column.
  • Added FeatureSource.GetAllFeatureAttributes and CanGetFeatureAttributesWithoutGeometry to read ids and column values without geometry; the SQL Server, PostgreSQL, GDAL and File Geodatabase sources do it natively.
  • Added ConcurrentAccess (Safe, UnsafeClone, UnsafeLock), which says whether a source can be read from several threads or must be copied or locked, replacing LayerBase.ThreadSafe, and LayerBase.Opacity/RasterSource.Opacity replacing Transparency.

Symbols

  • Added SVG point symbols (PointStyle.CreateStyleFromSvgFile, CreateStyleFromSvg, CreateStyleFromPathData, PointType.PathData) and PathDataParts in PointStyle.PathDataParts; they stay sharp and print as vector. Gradients, CSS and SVG text are not read.

.NET Framework

  • Improved .NET Framework packaging: Any CPU projects get the x86 and x64 SQLite engines and load the right one, and the System.Runtime.CompilerServices.Unsafe binding redirect fixes a TypeInitializationException on the first draw.

Dependencies

  • Upgraded SkiaSharp to v4.154.0, and Microsoft.Data.Sqlite and System.Text.Json to v10.0.9, with SQLite 3.53.4 through SQLitePCLRaw v3.0.5.

Bug Fixes

  • Fixed VectorMbTilesAsyncLayer reading MBTiles files without a tile scheme with flipped rows (now TMS), ArgumentOutOfRangeException on concurrent MBTiles reads, and closing a ThinkGeoMBTilesLayer leaving the .mbtiles file in use.
  • Fixed vector tile shapes shifting up to half a pixel between tiles, a MultiTile race at tile boundaries, MvtTilesAsyncLayer failing to open on Blazor WebAssembly, and ThinkGeoVectorMapsAsyncLayer drawing only its background in SingleTile.
  • Fixed WFS feature types losing their geometry when the service binds GML to a prefix other than "gml"; requests now send prefixed names with NAMESPACES and leave out PROPERTYNAME when all columns are wanted or it is refused.
  • Fixed WFS 2.0 schemas that declare the geometry in a base type, use element references, groups or imports, or reuse a type name; a type with several geometries is read through the first, as GeoServer, GDAL and QGIS do.
  • Fixed WfsV2FeatureSource taking a timestamp column for the geometry (services such as PDOK), and a WFS exception report, even with HTTP 200, returning no features instead of an error that says what the service said.
  • Fixed ArcGisServerRestVectorAsyncLayer returning geometry simplified for the last drawn view to hit tests and other queries, and OgcApiFeatureSource ignoring WebProxy and TimeoutInSeconds on its asynchronous path.
  • Fixed WmsServerLayer.MinScale and MaxScale always reading 0 (now read from 1.1.1 and 1.3.0 capabilities, with HasMinScale and HasMaxScale), and a second or canceled WmsAsyncLayer.OpenAsync throwing.
  • Fixed WMTS layers failing to open when the server gives its CRS as a URI, such as http://www.opengis.net/def/crs/OGC/1.3/CRS84, and cached WMTS capabilities not being found offline after a restart.
  • Fixed web layers leaking connections (they now dispose the HttpClient they create and leave yours alone), opening one service several times when tiles opened it in parallel, and treating a timed-out open as a success.
  • Fixed raster XYZ layers (Bing Maps and others) printing blank on servers, now capped by XyzTilesAsyncLayer.MaxConcurrentTileLoads, and overzoomed tiles (RenderBeyondMaxZoom) bypassing the tile cache or throwing.
  • Fixed GeoTIFF files with unsigned SHORT strip byte counts failing to read, and SkiaRasterSource keeping its decoded image after Close, which grew memory as layers were opened and closed.
  • Fixed raster tile layers drawn in another projection (OpenStreetMap, ThinkGeo Cloud raster, XYZ) showing seams or bands, smearing or throwing past the edge of the projected world (Robinson, Mollweide), and azimuthal maps cut to a sliver.
  • Fixed a view past a projection's world (a narrow Robinson map) throwing "does not pass our simple validation", an EPSG:4326 raster XYZ layer throwing a PROJ error at zoom 0, and projected tiles missing their last pixel row.
  • Fixed PointZ, PointM and multipoint shapefiles drawing nothing, shapefile GetFeatureIds returning ids of records with no shape, and GpxFeatureSource adding the whole track again each time it was reopened.
  • Fixed the static BaseShape.ScaleTo(shape, scale) changing the shape passed in (it now returns a scaled copy), and a feature with no geometry throwing when read through a ProjectionConverter or drawn by an AreaStyle.
  • Fixed concurrent FeatureSource.Open and Close calls corrupting a source, columns added through InMemoryFeatureLayer.Columns missing from GetColumns(), and in-memory queries missing features after InternalFeatures changed.
  • Fixed MapInfo TAB editing: attribute indexes are rebuilt correctly after a commit, copied features are added, committing through a ProjectionConverter keeps the stored coordinates, and zoom-level styles override embedded styling.
  • Fixed scale-limited layers and zoom-level styles switching at the wrong scale, and features at tile edges being missed, on high-DPI canvases (ScaleFactor above 1).
  • Fixed kriging grid interpolation hanging when asked for more neighbors than the data has, and reverse geocoding throwing ArgumentNullException when no location is found near the point.
  • Fixed the NOAA weather sources: a duplicate station id no longer leaves the stations layer empty, requests time out after 20 seconds (TimeoutInSeconds), and both sources work on Blazor WebAssembly.
  • Fixed LegendAdornmentLayer starting a new column because of a rounding difference and its layout when it has no items, and LogoAdornmentLayer throwing before its image is set.
  • Fixed labels jumping by a pixel against the map while panning and label fills wobbling inside their halos on bitmap canvases, and an access violation in text drawing when tiles are rendered in parallel.
  • Fixed SkiaGeoCanvas not finding installed Windows fonts whose display name differs from their family name, such as "Franklin Gothic Medium", and a GeoFont with both Underline and Strikeout drawing only the strikeout.
  • Fixed LineStyle throwing for a GeoPen made from a hatch, texture or gradient brush (the line is now stroked with that brush), and GeoLinearGradientBrush.WrapMode being ignored, which made some PDF viewers drop gradients.
  • Fixed line labels disappearing at random while zooming MultiTile overlays when they crossed a tile edge, and labels of lines that cross the dateline drawn off-center or not at all (with WrapDateline they are labeled once).
  • Fixed multi-line polygon labels, such as a TextStyle with a DateFormat, drawn as one line on top of each other, and TextStyle.FittingPolygonInScreen being ignored when LabelAllPolygonParts is on.
  • Fixed ValueStyle, ClassBreakStyle, GradientStyle, IconValueStyle and RegexStyle throwing when a feature's column value is null or missing.

ThinkGeo.Gdal:

  • Upgraded ThinkGeo.Gdal to use GDAL v3.12.1 with PROJ v9.7.1, for both Windows and Linux.
  • Added GdalGrid to read a band of any GDAL raster (GRIB2, NetCDF, GeoTIFF...) as values or as an InMemoryGridSource for GridRasterLayer.
  • Added GdalRasterSource.WarpProjection to warp a raster to another projection when it opens and SourceProjection to override a wrong or missing projection, and GdalRasterLayer.GdalCacheMax and EcwGdalRasterLayer.EcwCacheMax.
  • Fixed ThinkGeo.Gdal using another copy of gdal.dll already loaded in the process, which could crash Gdal.AllRegister, and GDAL data and PROJ files not being found in apps published with dotnet publish -r <rid>.
  • Fixed ThinkGeo.Gdal replacing PROJ search paths the application had set, and projects whose name contains a hyphen failing to build with CS1514 because a GdalConfiguration class was added to them.
  • Fixed MrSID and VRT mosaic reads failing at the dataset edge, 16-bit or five-band rasters writing past their image, rasters closed mid-read or open at exit crashing the process, and GdalRasterSource locking its world file.
  • Fixed GdalProjectionConverter drawing the world again in the corners of Equal Earth or sinusoidal maps, and GdalFeatureSource reading NULL integers as 0, losing ids on multi-layer files and formatting values per machine.

ThinkGeo.FileGeoDatabase:

  • Upgraded ThinkGeo.FileGeoDatabase to use the latest File Geodatabase API v1.5.5.
  • Added FileGeoDatabaseFeatureSource.GetTableInfos (also on the layer) to list every table with its geometry type without opening it.
  • Improved speed, most of all on network shares: listing and opening tables reads the geodatabase catalog in one query, and GetFeatureIds no longer reads every feature.
  • Fixed closing one File Geodatabase source breaking other sources on the same geodatabase, a geodatabase left open crashing .NET Framework apps on exit, and rows without a shape being returned by feature reads.

ThinkGeo.Cad:

  • Upgraded ThinkGeo.Cad to use the latest ODA SDK v27.9.
  • Added the CadLayerNameColumnName, CadColorColumnName, CadWidthColumnName and CadStyleKindColumnName columns to CadFeatureSource, so each entity's own layer, color, width and style kind can be used in styles and queries.
  • Fixed apps using ThinkGeo.Cad crashing or hanging at exit, including while a DWG was still being read.

ThinkGeo.Oracle:

  • Upgraded ThinkGeo.Oracle to use Oracle Instant Client v23.26.4 with the GDAL v3.12.1 Oracle plugins.
  • Fixed OracleFeatureLayer returning only the features crossing the antimeridian for views wider than about 180 degrees; it now queries with Oracle's native SDO_FILTER.

ThinkGeo.SqlServer:

  • Upgraded ThinkGeo.SqlServer to use Microsoft.Data.SqlClient v6.1.8.
  • Fixed connections that failed after the move to Microsoft.Data.SqlClient: a connection string that sets neither Encrypt nor TrustServerCertificate now gets TrustServerCertificate=True, as before.
  • Fixed WhereClause: it accepts a bare condition, applies to GetFeatureIds, and no longer leaves features outside a stale cached extent after the table is edited elsewhere.
  • Fixed the SRID being missed when the first row has no geometry, geography queries near the poles and the dateline, the spatial index of another geometry column being used, and values formatted differently per machine.

ThinkGeo.PostgreSql:

  • Upgraded ThinkGeo.PostgreSql to use Npgsql v8.0.9.
  • Improved PostgreSqlFeatureSource to read attributes without reading geometry and to format values the same on every machine.

ThinkGeo.NauticalCharts:

  • Added GetFeatureDescription to NauticalChartsFeatureLayer and NauticalChartsFeatureSource, which translates a feature's S-57 codes into plain names and values (for example COLOUR "3;1" to "red, white").
  • Added NauticalChartsFeatureLayer.ExportDefaultStyleFile to export the built-in S-52 style file for editing.
  • Fixed S-52 symbols, soundings, light sectors and pattern fills drawing too small on high-DPI screens.

ThinkGeo.Printers:

  • Improved PrinterGeoCanvas to print the new page-layout layers of ThinkGeo.Core too, and to honor a comma-separated font list, falling back to Noto Sans and then Segoe UI instead of letting GDI+ substitute a font silently.
  • Moved PrinterPageSize, PrinterOrientation, PrinterZoomLevelSet and five other printer types from ThinkGeo.Printers to ThinkGeo.Core; they are forwarded, so code compiled against 14.x keeps running.
  • Fixed raster and tile layers inside a MapPrinterLayer printing too large when the print Dpi is raised, and its BackgroundMask outline printing as a hairline while map content ran past the frame.
  • Fixed layers inside a MapPrinterLayer choosing their zoom level for the wrong scale, and ScaleLinePrinterLayer drawing too long, in the print preview on high-DPI displays.
  • Fixed PrinterGeoCanvas measuring text differently from how it draws it (centered labels drifted, text overflowed its box), and LegendPrinterLayer starting a new column because of tiny rounding differences.

ThinkGeo.UI.Blazor Namespace:

New Features & Improvements

MapLibre GL renderer

  • Upgraded the bundled MapLibre GL JS to v6.16.0.
  • Added a MapLibre GL JS renderer behind the same MapView: WebGL 2 drawing with tilt, rotation, 3D terrain and buildings, and a globe view. Existing overlays, markers, popups, adornments, editing and measuring work on it.
  • Added MapView.Renderer (MapViewRenderer.Auto, MapLibre, OpenLayers) and MapView.ActiveRenderer; Auto uses MapLibre when everything on the map is Web Mercator and OpenLayers otherwise (a non-meter MapUnit, a WMTS overlay, a reprojected layer).
  • Improved errors: a layer the MapLibre renderer cannot draw, such as one reprojected to a non-Mercator projection after the map was created, now names the layer, overlay, projection and renderer to use instead of drawing in the wrong place.

Camera: tilt, rotation and globe

  • Added MapView.Pitch (0 to 85 degrees) with GetPitchAsync and SetPitchAsync; binding it to a field tilts the map when the field changes, and markers and popups stay anchored to the ground (MapLibre renderer).
  • Added MapView.Bearing (degrees counter-clockwise from north) with GetBearingAsync and SetBearingAsync on both renderers, and EnableAltDragRotation for Alt-drag rotation on OpenLayers.
  • Added MapView.DisplayProjection and SetDisplayProjectionAsync to show the map flat (DisplayProjection.WebMercator), as a Globe or in VerticalPerspective; tiles and coordinates stay Web Mercator, so nothing is fetched again (MapLibre renderer).
  • Added MapView.ZoomToAsync(center, scale, bearing, durationInMilliseconds) to move the camera at once or animated (a null bearing keeps the rotation), and MapView.ZoomToExtentAsync to fit a whole extent in the map.
  • Added MapView.ZoomScales (replacing ZoomLevelSet), MinimumScale and MaximumScale, SetNavigationLimitsAsync to change the limits and RestrictExtent at run time, and ZoomToMinimumZoomAsync (the last two on MapLibre).
  • Changed GetCurrentExtentAsync on the MapLibre renderer to return the ground the map covers looking straight down at its center and scale, unchanged by tilt or rotation, as CurrentExtent does on the desktop.

Vector tiles, style.json and MapStyle (VectorTileOverlay)

  • Added VectorTileOverlay.Style, which takes a MapStyle composed in code beside the style.json text or URL in StyleJson; changing the style restyles in place without fetching tiles again (MapLibre renderer).
  • Added VectorTileOverlay.FeatureSources and SourceId to draw your own feature sources (shapefiles, databases, in-memory features) with a style: the server cuts them into vector tiles on demand over the Blazor circuit, with no tile URL to host.
  • Added VectorTileOverlay.PushThreshold (5,000 by default), which sends small in-memory feature sources to the browser whole so panning, zooming and moving a feature need no server requests, and IsSourceStatic for sources that never change.
  • Added VectorTileOverlay.Cluster, ClusterRadius and ClusterMaxZoom to group point features into numbered clusters that split as the map zooms in (MapLibre renderer).
  • Added MBTiles and PMTiles vector archives (MbTilesVectorTileSource, PmTilesVectorTileSource) composed into a MapStyle: they are served to the browser over the circuit and overzoomed past the archive's deepest zoom.
  • Added VectorTileOverlay.RasterTileSource and RasterSourceId to serve raster tiles from the application, such as raster MBTiles, PMTiles or a z/x/y folder (MbTilesRasterTileSource, PmTilesRasterTileSource), into a MapStyle raster layer.
  • Added ThinkGeo Cloud vector styles to VectorTileOverlay: new MapStyle(ThinkGeoVectorStyles.Light, new ThinkGeoVectorTileSource(apiKey)) draws them, with the API key passed to the browser's tile requests.
  • Added MapStyle.AddFeatureLayer for classic feature layers: they are written as style.json and drawn by VectorTileOverlay, including value, class-break and label styles.
  • Added the terrain, sky and light of a style (MapStyle.SetTerrain, SetSky, SetLight) to the MapLibre map, and 3D buildings: ThinkGeoCloudVectorMapsOverlay GL styles and your own fill-extrusion layers rise when tilted.
  • Improved VectorTileOverlay drawing: features crossing the antimeridian are drawn whole with no seam, and labels in a font the ThinkGeo glyph server lacks (such as "Arial Bold") use Noto Sans of the same weight.

Heatmaps, isolines and particle flow

  • Added heatmap layers in a VectorTileOverlay style over its feature sources, drawn in the browser; radius, intensity, weight and colors can change at run time without refetching (MapLibre renderer).
  • Added VectorTileOverlay.Isolines (IsolineOverlayOptions) to interpolate scattered values on the GPU and draw contour lines, color bands and labels; GetIsolineFieldAsync reads the field back as an IsolineFieldSnapshot (MapLibre renderer).
  • Added wind and current fields: MapStyle.AddParticleFlow draws animated particle streams and MapStyle.AddVectorField arrows that move along the flow, colored by speed, with the same shaders and pace as the desktop GPU map (MapLibre renderer).

Markers

  • Added CompositeMarkerStyle to draw several marker styles at one position, such as a glow under an icon, and RadialGradientMarkerStyle for a fading halo sized in pixels (RadiusInPixel) or map units (RadiusInMapUnits) (OpenLayers renderer).
  • Added Marker.HoverStyle, PointMarkerStyle.AnimationFrames and AnimationDuration, and marker selection (MarkerOverlay.EnableSelection with Ctrl-click or Ctrl-drag, OnSelectionChanged, Marker.IsSelectable, SelectionStyle) (OpenLayers renderer).

Map tools and events

  • Added CompassMapTool (shows the bearing, turns back to north) and HomeMapTool (Center, Zoom or Scale, Bearing, Pitch), shown or hidden while the map runs with MapView.SetMapToolVisibilityAsync and MapToolKind.
  • Added ZoomBarMapTool.UseNavigationStyle for the desktop-style navigation control with pan buttons, a center button (CenterButtonCenter, CenterButtonZoom, CenterButtonBearing, CenterButtonPitch) and PanOffset.
  • Added MapView.OnReady and WhenReady (the map and its declared overlays are ready), ActualWidth and ActualHeight, and OnCurrentExtentChangedInAnimation, raised about 20 times a second while the map moves, with extents and bearing.
  • Added AdornmentOverlay.RedrawWhileMoving to redraw adornments such as scale bars continuously during zoom and pan (MapLibre renderer).

Editing, measuring and export

  • Added EditOverlay and MeasureMapTool support on the MapLibre renderer: point, line, polygon, rectangle and circle drawing, vertex editing, and length and area measuring, including across the antimeridian.
  • Added EditOverlay.AddFeature(shape, featureId, columnValues), which keeps a circle supplied by the application a circle, and editing of a line stored split at the antimeridian (DatelineHelper.Split) as one continuous line.
  • Added MapView.ExportImageAsync(fileName) to download the map as shown, tilt included, as a PNG, and MapView.GetImageAsync to get the PNG bytes in the application (MapLibre renderer).

Hosting

  • Improved hosting: maps, overlays, markers, popups and map tools release their browser resources when removed, several maps on a page or a reconnecting circuit no longer interfere, and a script load error names the missing file.

Bug Fixes

  • Fixed LayerOverlay, WmsTileOverlay and WmtsTileOverlay redrawing every tile, so icons and shapes flashed, on each pan or zoom once any parameter such as WrappingMode was set.
  • Fixed LayerOverlay.RedrawAsync blanking the overlay until the new tiles arrived (the old tiles now stay until replaced, also on repeated redraws), and transparent overlays drawing tiles twice while a zoom step loaded.
  • Fixed WmsTileOverlay and WmtsTileOverlay ignoring server, layer, style, matrix set and parameter changes made at run time, and a rebuilt WMS or WMTS overlay moving above all other overlays.
  • Fixed RestrictExtent only clamping the map center, so half a view beyond the extent stayed reachable, and its zoom-out limit never applying to fixed-size maps.
  • Fixed MapView.SetCenterAsync failing in the browser.
  • Fixed RedrawAsync on an overlay throwing "The Overlay is not initialized yet" when called as soon as the map loaded, most often with long polling; MapView.IsLoaded now turns true after the declared overlays are attached.
  • Fixed overlays, markers and popups removed from the page, for example by an @if or by removing a marker from SimpleMarkerOverlay.Markers, staying on the map.
  • Fixed marker overlays requesting their markers again in a loop and flickering after a redraw, and InMemoryMarkerOverlay closing a feature source the application had opened.

ThinkGeo.UI.WebApi Namespace:

New Features & Improvements

  • Added VectorTileOverlay to serve Mapbox vector tiles from a Web API action, cut on demand from feature sources (FeatureSourceVectorTileSource) or read from MBTiles, PMTiles and .tgtiles archives (.NET 8 only).
  • Added AdornmentOverlay to draw adornment layers such as scale bars, legends and north arrows into one transparent image of the map's size, laid over a browser map.
  • Added LayerOverlay.GetTileImageAsync(zoom, x, y) to return one z/x/y raster tile as PNG for XYZ routes, using TileCache when one is set; tile x and y are long.
  • Added Overlay.GetImageAsync(width, height, extent) and Overlay.DrawAsync(canvas), which draw asynchronously and honor the request's cancellation token, so the request thread is free while layers fetch.
  • Added Overlay.MapUnit: extents are read in it and tiles follow its grid, Web Mercator for meters and the two-tile EPSG:4326 world for decimal degrees.
  • Added asynchronous layers such as XYZ tile services, WMS and WMTS to LayerOverlay, which raises DrawingLayer and DrawnLayer for them too.

Bug Fixes

  • Fixed LayerOverlay throwing an InvalidCastException when its Layers contained an asynchronous layer.
  • Fixed Overlay.DrawingExceptionMode (DrawAndThrowException now draws the error and throws, and IgnoreException ignores it) and Overlay.IsVisible being ignored when drawing; a hidden overlay now draws nothing.

Upgrading from ThinkGeo 14:

Licensing

  • ThinkGeo 15 licenses developers, not machines: each developer keeps a license key file that is checked when the project builds, and deployed apps need nothing installed or activated. ThinkGeo 14 licenses do not carry over.
  • See the License Guide for ThinkGeo 15 for license keys, the 30-day trial, subscriptions and renewals, the build messages and build servers.

Target frameworks and dependencies

  • ThinkGeo.UI.Blazor targets .NET 8 and .NET 10 (Microsoft.AspNetCore.Components.Web 8.0.33 and 10.0.14) and bundles MapLibre GL JS 6.16.0; ThinkGeo.UI.WebApi targets .NET Framework 4.6.2 and .NET 8.
  • ThinkGeo.Core uses SkiaSharp 4.154.0, Microsoft.Data.Sqlite 10.0.9, System.Text.Json 10.0.9 and SQLitePCLRaw 3.0.5 (SQLite 3.53.4, fixing CVE-2025-6965); NetTopologySuite stays at 2.6.0.
  • ThinkGeo.Gdal uses GDAL 3.12.1 with PROJ 9.7.1 on Windows and Linux and targets .NET Framework 4.6.2 and .NET 8 instead of .NET Standard 2.1; apps that reference the GDAL package directly must move to 3.12.1.
  • ThinkGeo.FileGeoDatabase uses the File Geodatabase API 1.5.5 (Expat, libxml2 and libxslt security fixes) and targets .NET Framework 4.8 and .NET Standard 2.1, so .NET Framework apps need 4.8 or later.
  • ThinkGeo.Cad uses the ODA CAD SDK 27.9, ThinkGeo.Oracle Oracle Instant Client 23.26.4 with the GDAL 3.12.1 Oracle plugin, ThinkGeo.SqlServer Microsoft.Data.SqlClient 6.1.8, and ThinkGeo.PostgreSql Npgsql 8.0.9.
  • The native packages ship an app-local Microsoft Visual C++ runtime 14.51.36247.0 (ThinkGeo.Dependency.MicrosoftVisualCRunTime140), and ThinkGeo.Printers uses System.Drawing.Common 9.0.22.

Removed and renamed APIs

  • Removed the ThinkGeo.Core APIs that were obsolete in 14.x, such as XyzTileAsyncLayer, NativeImageRasterLayer, Layer.RequestDrawing, TileSnappingMode, ZoomLevelSnappingMode, LowerThreshold/UpperThreshold and GdalFeatureSource.ActiveLayer.
  • Renamed, now compile errors: CanGetBoundingBoxQuickly → CanGetBoundingBoxWithoutScan, CanGetCountQuickly → CanGetCountWithoutScan, LayerBase.ThreadSafe → ConcurrentAccess, DrawingQuality.Default → Standard, DataGridResizeMode.Default → AutoFit.
  • ThinkGeo Cloud: CloudGeocodingOptions.SearchMode, ResultDetail, LocationType and the Overture options, and the reverse geocoding SearchArea and SearchLine, are compile errors; use SearchPoint or SearchPoints with a radius.
  • The GeoCanvas.DrawTextWithScreenCoordinate and DrawTextWithWorldCoordinate parameters are renamed from upperLeft* to center*, which breaks calls with named arguments; the ThinkGeo 14 ThinkGeoLicenseStatus values are compile errors.
  • Removed without an earlier warning: BuildingAreaStyle, OsmBuildingAreaStyle and BuildingShadowMode (on the MapLibre renderer, use fill-extrusion layers in a style), ZoomSnapDirection from ThinkGeo.Core and IMapArguments.GetSnappedExtent.
  • Custom Blazor overlays: do setup and cleanup in the new protected virtual InitializeAsyncCore() and ReleaseAsyncCore(); InitAsync and ReleaseAsync still run, but now also coordinate initialization, rollback and disposal.
  • Web API: Overlay.Draw and DrawCore are obsolete (override DrawAsyncCore(GeoCanvas, CancellationToken) and call GetImageAsync or DrawAsync), and DrawingLayerOverlayEventArgs.DrawingLayer and DrawnLayerOverlayEventArgs.DrawnLayer are LayerBase.

Deprecated APIs

  • Deprecated: ThinkGeoVectorMapsAsyncLayer → ThinkGeoVectorTileAsyncLayer, GridFeatureLayer → GridRasterLayer, GraticuleFeatureLayer → GraticuleAdornmentLayer, HeatStyle → HeatmapStyle, GoogleMapsAsyncLayer → GoogleMapsStaticAsyncLayer.
  • Deprecated: WfsFeatureLayer → WfsAsyncLayer, OgcApiFeatureLayer → OgcApiAsyncLayer, the static WfsV2AsyncLayer.GetLayers and GetCapabilities → their Async versions, LayerBase.Transparency → Opacity, and LayerBase.Background → a BackgroundLayer.
  • The classic ThinkGeo.Printers layers (MapPrinterLayer, PagePrinterLayer and the rest of the PrinterLayer family) and PrinterHelper still print as before but are deprecated and will be removed after v15.4: move to the page-layout layers.
  • Also deprecated, with no replacement: UsgsDemFeatureLayer and MapsQueryCloudClient. The new obsolete warnings break builds that treat warnings as errors; each message names the replacement and the release that removes it.

Behavior changes

  • MapLibre GL JS 6 ships as maplibre-gl.mjs and maplibre-gl-worker.mjs. ASP.NET Core serves .mjs correctly; plain IIS and other static hosts need a .mjs to text/javascript MIME mapping, or the map does not load.
  • Blazor maps in Web Mercator now draw with MapLibre (MapViewRenderer.Auto). Set Renderer="MapViewRenderer.OpenLayers" to keep 14.x rendering; the new marker styles, hover, selection and animation, and ProgressiveZooming need OpenLayers.
  • Blazor MapView.Width and Height keep the values you set (read ActualWidth and ActualHeight for pixels), and MapView methods called before the map has loaded now wait for it instead of returning null, doing nothing or throwing.
  • Blazor Overlay, Marker, MapTool and Popup are disposable and MapView is IAsyncDisposable; an overlay or marker removed from markup leaves the map, a Marker without a Style shows a bundled pin, and the map shows attribution.
  • Web API LayerOverlay.Draw no longer composes its image from TileCache tiles (only GetTileImageAsync uses the cache), and DrawingExceptionMode and IsVisible are now honored.
  • ThinkGeoSettings.PreserveZ is true by default: 3D shapefiles and GDAL sources return and write 3D data, and editing a Z or M shapefile in 2D mode throws. Set it to false once at startup, before opening any layer, for 14.x behavior.
  • Layer.Open and AsyncLayer.OpenAsync now throw when opening fails, unless the layer's DrawingExceptionMode is DrawException, which still paints the error on the next draw.
  • Maps look different: the default GeoFont is Noto Sans instead of Arial (text can measure and wrap differently), GeoLinearGradientBrush clamps instead of repeating, and style.json layers use the new engine and MapLibre labels.
  • MaxExtents.SphericalMercator is now exactly the Web Mercator world (0.11 m larger) and ThinkGeoMaps, MapBoxMaps and BingMaps equal it.
  • Touches and TopologicalEqual queries on a source with a ProjectionConverter now return no features: coordinates converted between projections never coincide exactly, so these exact tests could only be decided by rounding.

Recompile

  • The ThinkGeo assemblies are version 15.0.0.0: rebuild code compiled against 14.x.

14.5

14.5.5

Release date: 08/31/2026

ThinkGeo.Core Namespace:

Bug Fixes

  • Fixed a performance regression that made GeoTiffRasterLayer noticeably slower than 14.4.5 when drawing strip-organized GeoTIFF files, because the whole decoded image was copied again for every drawn tile.

14.5.4

Release date: 07/31/2026

ThinkGeo.Core Namespace:

New Features & Improvements

  • Added GeoRadialGradientBrush for filling shapes with a center-to-edge radial gradient, using either a two-color (centerColor, edgeColor) constructor or a collection of GeoColorStop values for multi-stop gradients.

Bug Fixes

  • Fixed nested GroupAsyncLayer throwing "A task may only be disposed if it is in a completion state" on every redraw when a GroupAsyncLayer contains another asynchronous layer.
  • Fixed a heap buffer overrun in GdalProjectionConverter coordinate transformation that could corrupt memory and crash 32-bit (x86) processes.

ThinkGeo.UI.Blazor Namespace:

New Features & Improvements

  • Added WrappingMode to ThinkGeoCloudRasterMapsOverlay and ThinkGeoCloudVectorMapsOverlay so cloud raster and vector maps wrap continuously across the antimeridian when set to WrappingMode.WrapDateline.

Bug Fixes

  • Fixed LayerOverlay rendering a blank map with MvtTilesAsyncLayer because the browser's concurrent tiles repeatedly opened and closed the shared layer; each layer is now opened once per overlay.

14.5.3

Release date: 06/28/2026

ThinkGeo.UI.Blazor Namespace:

New Features & Improvements

  • Added VectorTileOverlay for displaying vector tiles from a Mapbox Style JSON URL or JSON text.
  • Added ThinkGeoCloudVectorMapsOverlay.StyleVersion and ThinkGeoCloudVectorMapsStyleVersion to support the latest ThinkGeo Cloud vector map styles.
  • Added BlazorTrackMode.Rectangle for click-drag rectangle drawing in EditOverlay.
  • Added GeometryInfo, CircleGeometryInfo, and EditOverlay.GeometryProjectionString so draw and modify events can expose circle-specific geometry metadata and geodetic radius calculation.

Bug Fixes

  • Fixed edit-overlay rendering issues for shapes that cross the antimeridian.
  • Fixed LayerOverlay dateline wrapping by applying wrapping mode and extent to child layers before drawing.
  • Fixed marker overlay redraw after zoom changes.

14.5.2

Release date: 06/02/2026

ThinkGeo.Core Namespace:

New Features & Improvements

  • Added tile-cache generation options for controlling maximum concurrency, request pacing, retry count, and retry delay when generating raster tile caches.

Bug Fixes

  • Fixed native dependency package metadata so File Geodatabase and GDAL native runtime files are copied into consuming applications.
  • Fixed rotated unscaled Skia image rendering so the full image is drawn instead of being clipped.
  • Fixed GDAL SQL query results for shapefiles and aggregate queries so result-set columns and typed values are returned correctly.

ThinkGeo.Printers:

  • Fixed ScaleLinePrinterLayer line and label alignment when rendering with scaled or high-DPI canvases.

14.5.0

Release date: 03/31/2026

ThinkGeo.Core Namespace:

New Features & Improvements

  • Added ArcGisServerRestVectorAsyncLayer for querying and rendering ArcGIS Server REST vector feature services.
  • Added WfsV2AsyncLayer for WFS 2.0 endpoints, with improved query string generation and property-name handling; it replaces WfsV2FeatureLayer for WFS 2.0.
  • Added Feature.MakeGeometryValid() to repair invalid geometries using NetTopologySuite.
  • Added Feature.IsGeometryValid(out TopologyValidationError validationError) to validate a geometry and return the validation error when it is invalid.
  • Added PolygonSeamRenderingMode to control polygon seam sealing independently of vector anti-aliasing and eliminate thin white seams between adjacent filled polygons with no outline.
  • Added RasterXyzTileAsyncLayer.MinZoomOfTheData and RenderBeyondMinZoom.
  • Added DrawingExceptionMode.IgnoreException; layers that throw exceptions can now be ignored
  • Made XyzTileOverlay.XyzTileAsyncLayer public.
  • Added LineStyle.OffsetFromLine for rendering lines at a parallel offset from the feature geometry.
  • Added mapbox:// URI support for sprites and glyphs referenced by MapBox style JSON.
  • Improved MapBox Streets v11 compatibility for line-pattern, fill-pattern, and advanced text-layout properties.
  • Standardized number parsing on CultureInfo.InvariantCulture to fix locale-specific coordinate and style parsing issues.
  • Upgraded magnetic declination data from IGRF13 to IGRF14.
  • Added XML round-trip serialization support for WebXyzRasterTileAsyncLayer.
  • Improved TextStyle formatting support for NumericFormat, DateFormat, and TextFormat.
  • Added per-character font fallback in SkiaGeoCanvas and the new CreatingSKTypefaceForCharacter event for custom font resolution.
  • Enhanced ScaleLineAdornmentLayer with AboveLabelTextStyle, BelowLabelTextStyle, AboveLabelMargin, and BelowLabelMargin, plus better default text sizing.
  • Added Noto Sans as the default fallback font.
  • Updated FileGeoDatabaseFeatureLayer.GetInternalProj4ProjectionParametersString() to return the table's spatial reference, enabling CRS detection without a .prj file.
  • Unified raster resampling under RasterResamplingMode across GeoTiff, Skia raster, and GDAL sources.
  • Added SkiaRenderingOptions for fine-grained SkiaGeoCanvas rendering configuration.
  • Reworked SkiaSharp bitmap/image ownership for better thread safety and lower contention in multi-tile rendering.
  • Cached StyleJsonTextStyle zoom-level state and icon lookups to remove repeated allocations on unchanged zoom levels.
  • Released ThinkGeoVectorMapsAsyncLayer feature data and style references immediately after each tile draw to reduce peak heap usage during concurrent rendering.
  • Replaced MultipolygonShape convex hull generation in PositionStyle with Andrew's monotone chain algorithm for faster, correct results.

Bug Fixes

  • Fixed FileGDB multipart polygon conversion so outer and inner rings are classified correctly and emitted as Polygon or MultiPolygon WKB as appropriate.
  • Fixed FileGDB polygon spatial queries throwing TopologyException from NTS.
  • Fixed a projected MvtTilesAsyncLayer rendering regression introduced in 14.4.x.
  • Fixed MVT tile seam artifacts when the overlay is in SingleTile mode.
  • Fixed incorrect label offsets when labels are placed on rotated lines.
  • Fixed the text-wrapping algorithm for CJK text so it no longer wraps mid-character.
  • Fixed text wrapping so it accounts for canvas ScaleFactor.
  • Fixed StyleJson icon/label conflict detection so the icon bounding box is included in the candidate region.
  • Fixed StyleJson icon placement so it scales correctly with canvas ScaleFactor.
  • Fixed thin white seams between adjacent filled polygons when outlines are disabled.
  • Fixed WmtsAsyncLayer failures with servers that use decimal-degree TileMatrix definitions.
  • Fixed ProjectionConverter not handling the +R proj4 parameter.
  • Fixed PointShape.GreatCircle() returning NaN coordinates for antipodal inputs.
  • Fixed OgcApiFeatureSource entering an infinite request loop when the server is offline.
  • Fixed an exception when zooming out past tiles with RenderBeyondMaxZoom enabled.
  • Fixed RenderBeyondMaxZoom not working for the decimal-degrees map unit.
  • Fixed intermittent font rendering corruption where characters could mix between glyphs.
  • Fixed SkiaRasterSource failing to load PNG images from memory streams.
  • Fixed a CartographicTiles resampling regression introduced in 14.4.x.
  • Fixed an AsyncLocker threading conflict.
  • Fixed a DrawGlyph thread-safety issue.
  • Fixed labels appearing below the line centerline instead of centered on it.
  • Fixed TextStyle.TextPlacement left and right being swapped for point features.
  • Fixed GeoJsonFeatureSource failing to parse features with special characters in property values.
  • Fixed images appearing blurry when pixel-stretched in a 14.4.x regression.
  • Fixed SkiaSharp resource leaks and GeoImage lifecycle issues under concurrent tile drawing.
  • Fixed some meter-based projections failing to compute intersections against the SphericalMercator max extent.
  • Fixed GeoCanvas.Clear() not taking effect in certain rendering scenarios.
  • Fixed adornments rendering incorrectly on canvases with ScaleFactor > 1.
  • Updated the NOAA weather alerts feed URL to https://api.weather.gov/alerts/active.atom.

ThinkGeo.Gdal:

  • Updated GDAL to 3.11.3.
  • Added ECW and JPEG2000 format support on Linux.

ThinkGeo.FileGeoDatabase:

  • Updated the FileGDB API dependency to 1.5.3, enabling retrieval of a table's spatial reference (SRID).
  • Fixed multipart polygon and multi-ring conversion so clockwise outer rings and counter-clockwise inner rings are identified correctly, and features with multiple outer rings are emitted as valid WKB MultiPolygon.

ThinkGeo.SqlServer:

  • Upgraded from System.Data.SqlClient to Microsoft.Data.SqlClient.

ThinkGeo.UI.Blazor Namespace:

New Features & Improvements

  • Added WmtsTileOverlay.
  • Added EditOverlay feature editing through JavaScript interop, including feature selection, translation, and vertex editing.
  • Added automatic client-asset loading with fallback support for legacy _Host pages and CDN hosting.

Bug Fixes

  • Fixed Blazor WebAssembly (browser-wasm) compatibility issues.
  • Fixed marker-style propagation issues and circle-edit regressions.
  • Fixed client bootstrap failures on legacy hosting environments.

14.4

14.4.5

Release date: 02/26/2026

ThinkGeo.Core Namespace:

  • Fixed a TextStyle.TextPlacement regression (introduced in v14.4.0 and reported against v14.4.4) where left/right placements were mirrored.
  • Fixed a zoom-level request filtering regression where online layers could still send requests outside the configured style zoom range, causing unnecessary network traffic.

14.4.4

Release date: 01/28/2026

ThinkGeo.Core Namespace:

  • Fixed an issue where MaskMargin is not correct

14.4.3

Release date: 01/11/2026

ThinkGeo.Core Namespace:

  • Fixed an issue where the internal exceptions in OgcApiFeatureLayer/OgcApiFeatureOverlay are not thrown.
  • Improved HatchStyle:
    • Fixed a bug (introduced in v14.4.1) where HatchStyle cannot have transparent background
    • Fixed a bug (introduced in v14.4.1) where some of the items in GeoHatchStyle enumeration are not compatible with the ones in v14.4.0

14.4.2

Release date: 11/03/2025

ThinkGeo.Core Namespace:

  • XyzLruCache: Handles Capacity == 0 gracefully (effectively disables caching without errors).
  • Improved HatchStyle:
    • Fixed a bug (introduced in v14.4.1) where HatchStyle were not displayed
    • Rendering now respects the ScaleFactor, which make it work better on a High-Res screen
    • Added protected virtual method GeoHatchBrush.GetHatchPatternSvgCore to allow custom hatch patterns

14.4.1

Release date: 10/20/2025

ThinkGeo.Core Namespace:

  • Fixed an issue where creating a new table in a File GeoDatabase could fail.
  • Fixed an issue where the Projection property doesn't work in WmsAsyncLayer.
  • Added support for local sprite files in StyleJson.
  • Added HatchBrush support in WpfDrawingCanvas and unified HatchBrush behavior between WpfDrawingCanvas and SkiaCanvas.
  • Changed ProjectionConverter to suppress inner exceptions by default.
  • Improved performance by adding caching to Projection and WmtsAsyncLayer.

14.4.0

Release date: 10/10/2025

ThinkGeo.Core Namespace:

  • MvtTilesAsyncLayer greatly improved:

    • Supported Projection
    • Supported Vector Tile Caching
    • Enhanced robustness and reliability
  • WfsV2FeatureLayer improvements:

    • Added support for MultiPolygon geometries
    • Improved URI flexibility and automatic axis-order detection based on projection
    • Fixed a bug preventing WFS from working correctly when added to a LayerOverlay.
    • Enhanced robustness and reliability.
  • Upgraded ThinkGeo.Cad to use the latest ODA SDK v26.7.

  • Fixed thread-safety issues in GdalProjectionConverter.Convert().
  • Created SkiaGeoCanvas.CreatingSKTypefacesForText event to give user an option to customize the loading SKTypeface.
  • Fixed incorrect anchoring behavior in ScaleLineAdornmentLayer.
  • Fixed exception when both WhereClause and MaxRecordsToDraw were set in PostgresFeatureSource.

14.3

14.3.2

Release date: 7/28/2025

ThinkGeo.Core Namespace:

  • Fixed an issue where MapPrinterLayer.Projection wasn’t respected in MagneticDeclinationPrinterLayer.
  • Fixed an issue where certain MultiPolygon geometries were not supported in WFS 2.
  • Enhanced WfsV2Layer to accept more flexible URIs (e.g. URIs containing ?SERVICE=WFS&VERSION=2.0.0).
  • Enhanced MvtAsyncLayer to support local MBTiles referenced in the style JSON.
  • Enhanced SkiaRasterLayer to lazily load only the needed tiles when the image is backed by a CPU‑resident pixel buffer.
  • Added a cache‑generation API: LayerBase.GenerateTileCacheAsync().

14.3.1

Release date: 6/3/2025

ThinkGeo.Core Namespace:

  • Fixed an issue where BulkSize was not applied in some cases when using OgcApiFeaturesSource.GetRequestUrlForFeatures.
  • Fixed an issue where WMS layer sent larger than necessary requests when the scale factor exceeded 100%.
  • Removed some restrictions on column names in feature sources (e.g., "[" is now a valid character in shapefile column names).
  • Deprecated BingMapsAsyncLayer; added support for AzureMapsRasterAsyncLayer.

ThinkGeo.UI.WebApi Namespace

  • Fixed an issue where runtime licenses did not function correctly in design-time scenarios on .NET Framework.

14.3.0

Release date: 5/7/2025

ThinkGeo.Core Namespace:

  • Streamlined the architecture of all XYZ-based layers and improved performance.
  • Added RenderBeyondZoom and ProjectionConverter support to all RasterXyzTileAsyncLayer types (including WmtsAsyncLayer, RasterMbTilesAsyncLayer, etc.).
  • Added a CacheGenerator API on RasterXyzTileAsyncLayer to create tile caches for a specified extent and zoom range.
  • Added support for MvtTilesAsyncLayer and enhanced MbVectorTilesLayer (now inheriting from VectorXyzTileAsyncLayer).
  • Added ProjectionConverter support to WmsAsyncLayer.
  • Exception Handling: Streamlined the error-handling workflow across all layers.
  • Updated to integrate the latest CAD package (ODA SDK 25.12).
  • Obsolete the following Nuget Packages and move the corresponding classes to ThinkGeo.Gdal
    • ThinkGeo.UnmanagedProj
    • ThinkGeo.MrSid
    • ThinkGeo.UnmanagedGeoTiff
    • ThinkGeo.Ecw
    • ThinkGeo.Jpeg2000
    • ThinkGeo.PersonalGeoDatabase
    • ThinkGeo.GeoPdf
    • ThinkGeo.Kml

ThinkGeo.UI.Blazor:

  • Fixed an issue that TileOverlay's cache not working in some cases

14.2

Release date: 10/10/2024

ThinkGeo.Core Namespace:

  • Upgraded ThinkGeo.Gdal to use Gdal v3.9.1 for both Windows and Linux.
  • Added the Weight property to GridCell in GridFeatureLayer.
  • Improved the performance of loading and saving tiles from/to the cache.
  • Fixed a performance issue where the license was being over-checked.
  • Enhanced support for sparse matrices (where some cells are null) in InMemoryGridFeatureSource
  • Made WMTSLayer auto-detect the server type (Restful or KVP).
  • Fixed an issue where the WMTSLayer was a couple of meters off at lower zoom levels.
  • Resolved a conversion issue between Srid and ProjString in the managed projection converter.

14.1

Release date: 6/6/2024

ThinkGeo.Core Namespace:

  • Added MbTilesLayer that renders the MBTiles v1.3 dataset using the standard StyleJson.
  • Added MbTilesRasterLayer that renders the standard MBRasterLayer

14.0

Release date: 5/1/2024

ThinkGeo.Core Namespace:

  • Added OGC Features API Support
  • Added WFS V2 Support

13.3

Release date: 4/16/2024

ThinkGeo.Core Namespace:

  • Fixed the issue that NoaaWeatherStationFeatureLayer not working
  • Fixed the issue that NoaaWeatherWarningsFeatureLayer not working
  • Fixed the issue that map border discrepancies when isGrayScale is set to true on MapPrinterLayer.
  • Fixed the alignment issues in LabelPrinterLayer when printing to PDF.
  • Enhanced LayerAsync by adding CancellationToken to OpenAsync() and CloseAsync() methods in AsyncLayer.
  • Enhanced RasterTileCache by support saving and retrieving tiles asynchronously.
  • Enhanced Docker compatibility by removing C++ redistributable installation from ThinkGeo.Core.
  • Enhanced Performance of ColorTransformation for large image layers. Added KML support through GDAL on Linux platforms.

13.2

Release date: 11/29/2023

ThinkGeo.Core Namespace:

  • Added the following classes with asynchronous data fetching to ThinkGeo.Core.Async namespace:

    • ArcGisServerRestLayer
    • BingMapsLayer
    • CloudMapClient
    • GoogleMapsLayer
    • HereMapsRasterTileLayer
    • LayerAsync
    • MapBoxStaticTilesLayer
    • OpenStreetMapLayer
    • RasterLayerAsync
    • RasterSourceAsync
    • ThinkGeoCloudRasterMapsLayer
    • ThinkGeoCloudVectorMapsLayer
    • WebBasedLayer
    • WmsRasterLayer
    • WmsRasterSource
    • WmtsLayer
    • XYZTileLayer
  • Upgraded the ThinkGeo.CAD dependencies to the latest version as of November 2023 (ODA 24.9).

  • Fixed the issue where a layer is not showed up correctly when setting a custom style to the DefaultStyle instead of adding it to the CustomStyles collection
  • Enhanced WmsLayer functionality with new helper methods and better server compatibility.

13.1

Release date: 7/7/2023

ThinkGeo.Core Namespace:

  • Optimized performance for layers at lower zoomlevels.
  • Enhanced the performance of NoaaWeatherStationsLayer and NoaaWeatherWarningsLayer.
  • Implemented AsyncLocker, replacing lock() internally wherever possible.
  • Added support for V2 and X2 to ThinkGeoCloudRasterMapsLayer. Note: V2 represents the 2nd version, and X2 signifies High DPI.
  • Added PositionStyle.AllowLabelNudging to permit label nudging.
  • Introduced FeatureSource to GridDefinition to leverage featureSource's spatial index during InterpolationModel calculations.
  • Fixed an issue causing GeoTiff to produce a vertical white line at certain zoom levels.
  • Fixed an issue where some WKTs failed to function properly with French system culture.

13.0

Release date: 11/29/2022

ThinkGeo.Core Namespace:

  • Improved the accuracy and performance of isolines.
  • Improved FileGeoDatabase performance and added more APIs using the latest FileGDB APIs(FileGDB_API_1.5.2) from ESRI.(Windows only)
  • Improved multiple columns labeling through TextStyle.TextContent
  • improved MagneticDeclinationAdornmentLayer by updating to the latest Geomagnetic Reference IGRF13 from: https://www.ngdc.noaa.gov/IAGA/vmod/
  • Improved the heatmap styling by updating its color palette.
  • Supported the GeoTiff files with separate planes and multiple strips
  • Supported the MrSid files with more than four bands(Windows only)
  • Supported HereMapsRasterTileLayer
  • Supported deleting/adding/editing columns for TabFiles.
  • Supported GeoPdf through NuGet package ThinkGeo.GeoPdf(Windows only)
  • Supported KML through NuGet packages ThinkGeo.Kml(Windows only)
  • Supported the latest CAD format by referencing the latest ODA dependencies from (https://www.opendesign.com/). (up to 2022)(Windows only)
  • Upgraded all the dependencies to the latest (up to 11/2022) and streamline the 3rd party dependency reference.
  • Updated the proj string of the SRIDs to the latest based on https://epsg.io/
  • Implemented an API to check if a license is activated: ThinkGeoProductLicense.GetCoreLicenseStatus()
  • Fixed the issue where a null numeric field in a shapefile returns bad results
  • Fixed the issue where internal exceptions are thrown when cached tiles are read/updated simultaneously.
  • Fixed the issue where the labeling of curved lines is not at the center in some scenarios.
  • Fixed the issue where some labels are cut in busy places like New York City in ThinkGeoCloudRasterLayer.

12.3

Release date: 11/6/2020

ThinkGeo.Core Namespace:

  • Created ThinkGeo.UI.XamarinForms edition.
  • Created MapBox layer and support MapBox static tile.
  • Open web browser instead of Product Center when no license was found.
  • Minimum supported .NET Framework version now has been updated to 4.6.2 from 4.6.1.
  • Add an API to the WorldFile class to allow it to save a world file to disk.
  • Added the API to convert feature collection to GeoJSON.
  • Added TopologyValidator class for validating shapes.
  • Added XYZ layer as the base class of all the XYZ-based layers.
  • Greatly improved the performance of web-based layers, such as bingmaps layer, googlemaps layer and thinkgeo cloud layers.
  • Request for X2 Google images if needed in Google Layer.
  • Fixed the issue where application cannot work on both X86 and X64 systems when compiling with .NET Framework under AnyCPU, by upgrading the drawing engine to SkiaSharp 2.80.2.
  • Fixed the issue where Proj String and EPSG number cannot be read correctly when opening a layer.
  • Fixed the issue where printing doesn’t work properly on High DPI printer.
  • Fixed the issue where the transparent background of a geotiff was not displayed properly.
  • Fixed the issue where a geoimage cannot be serialize/deserialize properly.
  • Fixed the issue where CAD layer throw a KeyNotFound exception in certain situations.
  • Fixed an issue where the Red and Blue channels of a geoTiff are inverted on Linux, iOS and Android.
  • Fixed the issue where drawing text with rotation angle other than 0 has some unexpected offset when zooming in to the lowest zoomlevel.
  • Support raster projection for the web-based layers such as google maps, bing maps, ThinkGeo cloud maps and mapbox maps.

12.1

Release date: 11/29/2019

ThinkGeo.Core Namespace:

  • Enhanced to support high resolution screen for ThinkGeo Cloud Maps.
  • Enhanced to support high resolution screen for GoogleMapsLayer.
  • Enhanced to support projection for WMTS layer.
  • Fixed a bug where UnmanagedProjProjectionConverter converts extent to internal projection incorrectly.
  • Fixed the font size issue for PointStyle.
  • Fixed a bug where the WKB of MultiLine Empty can't parse.
  • Fixed a bug where ThinkGeo Cloud Vector layer aren't rendered at zoom level 19.
  • Fixed a bug where the alpha component of GeoColor style didn't work.
  • Fixed a bug where TextBaseline can't support multi-line text.
  • Enhanced to support cancel drawing line.
  • Fixed a bug where the GeoImage being used is disposed for Noaa layer.
  • Enhanced to support Cad.
  • Enhanced to support multi-thread for projection converter.
  • Fixed a bug where FeatureSource.GetColumns method throws exception in multi-threads.
  • Enhanced to make SqliteFeatureLayer thread safe.
  • Added DrawText method for PositionStyle.
  • Added "PointStyle(GeoFont glyphFont, string glyphContent, GeoBrush fillBrush)" constructor for PointStyle.
  • Published PointStyle.DrawGlyph method.
  • Enhanced to support custom font for PointStyle.
  • Changed the default tile size value of ZoomLevelSet from 256 to 512.
  • Published PointStyle.DrawImage method.
  • Published PointStyle.DrawSymbol method.
  • Fixed a bug where the ProjectionConverter.ConvertToExternalProjection method doesn't work.
  • Fixed a bug where SqliteFeatureSource querying data from R-Tree index table throws exception.
  • Fixed a bug where the SqliteFeatureSource.GetFeaturesByIds method doesn't work.
  • Changed longitude and latitude parameter order for some API.
  • Enhanced to support GeoLinearGradientBrush for Printer and fixed bug the Printer get different result with the Map if polygon contains inner rings.
  • Fixed a bug where the angle of label of GeoLinearGradientBrush is incorrect .
  • Fixed an bug where when parsing tile format tiff image, throws "Array index is out of range" exception.
  • Enhanced to support background for layer.
  • Enhanced to support KeyColors for SkiaGeoCanvas.
  • Changed the default web proxy from null to DefaultWebProxy of system.
  • Fixed a bug where rendering tiff image is blurred.

ThinkGeo.UI.Blazor Namespace:

  • Fixed a bug where AdornmentOverlay.Redraw doesn't work.
  • Fixed a bug where RestrictExtent doesn't work when zooming out for ThinkGeo.UI.Blazor.
  • Renamed "MapView.MaxExtent" to "MapView.RestrectExtent" for ThinkGeo.UI.Blazor.
  • Changed longitude and latitude parameter order for some API.

12.0

  1. Merge all the managed layers to Core and used GDAL to redesign Unmanged Layers. Rename the packages name, here is latest package name;

  2. ThinkGeo.UI.Wpf

  3. ThinkGeo.UI.Blazor

  4. ThinkGeo.UI.WebApi

  5. ThinkGeo.Core

  6. ThinkGeo.Gdal
  7. ThinkGeo.Ecw
  8. ThinkGeo.Cad
  9. ThinkGeo.GeoTiff
  10. ThinkGeo.Jpeg2000
  11. ThinkGeo.MrSi
  12. ThinkGeo.UmanagedProj
  13. ThinkGeo.NuticalCharts
  14. ThinkGeo.FileGeoDatabase
  15. ThinkGeo.PersonalGeoDatabase
  16. ThinkGeo.Oracle
  17. ThinkGeo.Sqlite
  18. ThinkGeo.MsSql
  19. ThinkGeo.PostgreSql
  20. ThinkGeo.Printers

  21. ThinkGeo.Dependency.SQLite

  22. ThinkGeo.Dependency.MicrosoftVisualCRunTime140
  23. ThinkGeo.Dependency.NetTopologySuite
  24. ThinkGeo.Dependency.Npgsql
  25. ThinkGeo.Dependency.Printers
  26. ThinkGeo.Dependency.SkiaSharp
  27. ThinkGeo.Dependency.SqlClient
  28. ThinkGeo.Dependency.Jint
  29. ThinkGeo.Dependency.SQLite
  30. ThinkGeo.Dependency.WriteableBitmapEx

  31. Redesign GeoCanvas based on SkiaSharp.

  32. Updated all the C++ runtime to one single version, use MSVC140.

  33. Use one GDAL C# wrap instead of raster layer wrappers, like JPEG2000, ECW, MrSid, Tiff, .etc.

  34. Removed FDO, and SDF layer.

  35. Renamed our all MapControl to MapView.

  36. Used GDAL for S57 and FileGeoDatabase and PersonalGeoDatabase, this will inherit from GDAL Feature Layer.

  37. MapSuite TileCache/Tile Matrix, based on current design, the TileView, TileCache, Tile, Matrix are thread safe. It will improve the performance greatly.

  38. Matrix: Create/Calculate the matrix system for TileLayer and TileOverlay.

  39. Tile: The tiles for the cached items, the tile contains the tile data and tile location (z,x,y)
  40. TileCache: Tile Cache for ThinkGeo, it work with one tile.
  41. TileView: TileOverlay each tile view, it only draw the layers or render the drawing result in UI.

  42. Refine our MapSuite properties, make sure set one property won’t change other properties, like Map.Unit will update the map extent, .etc.

  43. Support Rotation for WPF.

  44. Support StyleJson.