Metadata-Version: 2.4
Name: orange-gis
Version: 0.4.0
Summary: GIS analysis and interactive mapping widgets for Orange
Author-email: Daeyong Shin <anespart1@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/anespart1
Keywords: orange3,gis,geopandas,spatial-analysis,mapping
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: GIS
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: Orange3<4,>=3.40
Requires-Dist: branca>=0.6
Requires-Dist: centerline>=1.1
Requires-Dist: esda>=2.6
Requires-Dist: folium>=0.17
Requires-Dist: geopandas<2,>=1.0
Requires-Dist: geopy>=2.4
Requires-Dist: jinja2>=3.1
Requires-Dist: libpysal>=4.12
Requires-Dist: mapclassify>=2.8
Requires-Dist: networkx>=3.2
Requires-Dist: numpy<3,>=1.26
Requires-Dist: osmnx<3,>=2.0
Requires-Dist: pandas<3,>=2.1
Requires-Dist: pyogrio<1,>=0.8
Requires-Dist: pyproj<4,>=3.6
Requires-Dist: scikit-learn>=1.4
Requires-Dist: shapely<3,>=2.0
Provides-Extra: text
Requires-Dist: Orange3-Text<2,>=1.16.3; extra == "text"
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-qt>=4.4; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: twine>=5; extra == "dev"
Dynamic: license-file

# Orange GIS

Orange GIS is an Orange add-on for loading, transforming, analysing, and
visualising geospatial data. The distribution name is `orange-gis`; its Python
package is `orangecontrib.orange_gis` because Python module names cannot contain
hyphens.

Version 0.4 targets Orange 3.40 and Python 3.11 or newer. It contains 30 Orange
widgets, including local-LLM toponym extraction through Ollama.

## Installation

When the package is published, install `orange-gis` through Orange's
**Options → Add-ons** interface. For a local wheel, select the generated
`orange_gis-0.4.0-py3-none-any.whl` in the same interface.

For development, always run pip with the Python interpreter that belongs to the
target Orange installation:

```powershell
& "<orange-python>" -m pip install -e ".[dev]"
```

The core package does not force-install Orange Text and its large language
resources. Install **Orange3-Text** separately through **Options → Add-ons** for
the workshop's word-cloud flow and the **Toponym to Corpus** widget, or use:

```powershell
& "<orange-python>" -m pip install "orange-gis[text]"
```

Without Orange Text, the remaining Orange GIS widgets still load; Toponym to
Corpus displays a focused installation message when used.

### GeoPandas and standalone Orange

GeoPandas remains the supported spatial-table backend in 0.4. Removing it would
not remove the compiled GEOS, PROJ, and GDAL/OGR capabilities needed by the GIS
widgets. Orange GIS therefore declares GeoPandas together with Shapely, PyProj,
and Pyogrio explicitly and uses Pyogrio for vector-file I/O.

On most supported Windows, macOS, and Linux/Python combinations pip installs
binary wheels. If the Orange Add-ons installation fails, check the exact Orange
Python environment instead of installing packages into another Python:

```powershell
& "<orange-python>" -m pip install --only-binary=:all: `
  "shapely>=2,<3" "pyproj>=3.6,<4" "pyogrio>=0.8,<1" "geopandas>=1,<2"
& "<orange-python>" -m orangecontrib.orange_gis.diagnostics
```

The first command deliberately fails when a compatible binary wheel is not
available; it does not attempt a fragile local GDAL build. The diagnostic
command reports the interpreter and the import status of Orange, GeoPandas,
Pyogrio, Shapely, and PyProj.

The dependency design and the criteria for any future non-GeoPandas backend are
documented in [docs/DEPENDENCY_STRATEGY.md](docs/DEPENDENCY_STRATEGY.md).

## Local Ollama toponym extraction

The **Ollama Toponym Extraction** widget sends text only to the configured
Ollama server. The default is the local API at `http://127.0.0.1:11434`; no
cloud API key or Python Ollama client is required.

Before the first run:

1. Install Ollama from <https://ollama.com/download> and restart Orange.
2. Download the default multilingual model with `ollama pull qwen3:4b`, or
   enter another installed model tag in the widget.
3. Connect an Orange table, select a string column, and run the widget.

Immediately before extraction, the widget checks the API and installed model
list. It shows a specific popup when Ollama is not installed, when the local
server is stopped, or when the selected model has not been downloaded. Ollama's
structured-output JSON schema is used for the result. Models are not downloaded
automatically because model files can be several gigabytes.

## Map architecture

Interactive maps remain embedded in the Orange widget with `QWebEngineView`.
One in-process HTTP service is shared by all open map widgets:

1. The first map widget starts a server bound to `127.0.0.1` on a random port.
2. Every widget receives a private session ID and random token.
3. `QWebEngineView` loads the map over HTTP.
4. Marker events return as token-protected JSON POST requests.
5. Closing the last map widget schedules automatic server shutdown.

There is no server subprocess, console window, iframe wrapper, temporary HTML
file, or Qt WebChannel object.

## Package layout

- `orangecontrib.orange_gis.geo`: GeoDataFrame validation and CRS helpers
- `orangecontrib.orange_gis.llm`: dependency-free local Ollama API client
- `orangecontrib.orange_gis.web`: loopback map server and web panel
- `orangecontrib.orange_gis.widgets`: 30 Orange widgets and resources
- `tests`: metadata, map-server, table, and Ollama-client tests

All Qt imports go through AnyQt. Result-producing text widgets retain the source
Orange table before appending their result columns.

## Build and validation

```powershell
& "<orange-python>" -m pytest
& "<orange-python>" -m build
& "<orange-python>" -m twine check dist/*
```

See [PUBLISHING.md](PUBLISHING.md) for the TestPyPI, clean-Orange, and PyPI
Trusted Publishing release gates.
