Metadata-Version: 2.4
Name: notlang
Version: 0.9.26
Summary: GIS uchun soddalashtirilgan buyruqlar tili (Python ustida ishlaydi) — Uzbek-friendly domain-specific language for GIS/RS
Author-email: Xushnudbek Rahimberganov <notgis@proton.me>
License-Expression: MIT
Project-URL: Homepage, https://notgis.top
Project-URL: Repository, https://github.com/notGIS/notlang
Project-URL: Issues, https://github.com/notGIS/notlang/issues
Keywords: gis,remote-sensing,geospatial,dsl,uzbekistan,earth-engine,copernicus
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Intended Audience :: Science/Research
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: geopandas>=0.14
Requires-Dist: rasterio>=1.3
Requires-Dist: matplotlib>=3.7
Requires-Dist: numpy>=1.24
Requires-Dist: shapely>=2.0
Requires-Dist: scipy>=1.10
Requires-Dist: lark>=1.1
Requires-Dist: requests>=2.28
Requires-Dist: pyproj>=3.5
Provides-Extra: jupyter
Requires-Dist: ipython>=8.0; extra == "jupyter"
Requires-Dist: ipyleaflet>=0.17; extra == "jupyter"
Provides-Extra: gee
Requires-Dist: earthengine-api>=0.1; extra == "gee"
Provides-Extra: interpolation
Requires-Dist: pykrige>=1.7; extra == "interpolation"
Provides-Extra: cartography
Requires-Dist: mapclassify>=2.6; extra == "cartography"
Requires-Dist: matplotlib-scalebar>=0.8; extra == "cartography"
Provides-Extra: threed
Requires-Dist: plotly>=5.0; extra == "threed"
Requires-Dist: pyvista>=0.44; extra == "threed"
Requires-Dist: trame>=3.0; extra == "threed"
Requires-Dist: trame-vtk>=2.0; extra == "threed"
Requires-Dist: trame-vuetify>=2.0; extra == "threed"
Requires-Dist: nest_asyncio2>=1.0; extra == "threed"
Provides-Extra: spectral
Requires-Dist: spyndex>=0.5; extra == "spectral"
Provides-Extra: hydrology
Requires-Dist: pysheds>=0.4; extra == "hydrology"
Provides-Extra: spatial-stats
Requires-Dist: scikit-learn>=1.3; extra == "spatial-stats"
Requires-Dist: esda>=2.5; extra == "spatial-stats"
Requires-Dist: libpysal>=4.9; extra == "spatial-stats"
Provides-Extra: cartography-extra
Requires-Dist: rasterstats>=0.19; extra == "cartography-extra"
Requires-Dist: contextily>=1.5; extra == "cartography-extra"
Requires-Dist: mapbox-vector-tile>=2.0; extra == "cartography-extra"
Provides-Extra: timeseries
Requires-Dist: xarray>=2023.1; extra == "timeseries"
Requires-Dist: rioxarray>=0.15; extra == "timeseries"
Provides-Extra: parquet
Requires-Dist: pyarrow>=14.0; extra == "parquet"
Provides-Extra: network
Requires-Dist: osmnx>=1.9; extra == "network"
Provides-Extra: webmap
Requires-Dist: folium>=0.15; extra == "webmap"
Provides-Extra: drive
Requires-Dist: google-api-python-client>=2.0; extra == "drive"
Requires-Dist: google-auth-oauthlib>=1.0; extra == "drive"
Requires-Dist: google-auth-httplib2>=0.1; extra == "drive"
Provides-Extra: vector-io
Requires-Dist: fiona>=1.9; extra == "vector-io"
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Requires-Dist: pytest-cov>=4.0; extra == "test"
Provides-Extra: full
Requires-Dist: ipython>=8.0; extra == "full"
Requires-Dist: ipyleaflet>=0.17; extra == "full"
Requires-Dist: earthengine-api>=0.1; extra == "full"
Requires-Dist: google-api-python-client>=2.0; extra == "full"
Requires-Dist: google-auth-oauthlib>=1.0; extra == "full"
Requires-Dist: google-auth-httplib2>=0.1; extra == "full"
Requires-Dist: pykrige>=1.7; extra == "full"
Requires-Dist: mapclassify>=2.6; extra == "full"
Requires-Dist: matplotlib-scalebar>=0.8; extra == "full"
Requires-Dist: plotly>=5.0; extra == "full"
Requires-Dist: pyvista>=0.44; extra == "full"
Requires-Dist: trame>=3.0; extra == "full"
Requires-Dist: trame-vtk>=2.0; extra == "full"
Requires-Dist: trame-vuetify>=2.0; extra == "full"
Requires-Dist: nest_asyncio2>=1.0; extra == "full"
Requires-Dist: spyndex>=0.5; extra == "full"
Requires-Dist: pysheds>=0.4; extra == "full"
Requires-Dist: scikit-learn>=1.3; extra == "full"
Requires-Dist: esda>=2.5; extra == "full"
Requires-Dist: libpysal>=4.9; extra == "full"
Requires-Dist: rasterstats>=0.19; extra == "full"
Requires-Dist: contextily>=1.5; extra == "full"
Requires-Dist: mapbox-vector-tile>=2.0; extra == "full"
Requires-Dist: xarray>=2023.1; extra == "full"
Requires-Dist: rioxarray>=0.15; extra == "full"
Requires-Dist: pyarrow>=14.0; extra == "full"
Requires-Dist: osmnx>=1.9; extra == "full"
Requires-Dist: folium>=0.15; extra == "full"
Requires-Dist: fiona>=1.9; extra == "full"
Provides-Extra: colab
Requires-Dist: ipyleaflet>=0.17; extra == "colab"
Requires-Dist: earthengine-api>=0.1; extra == "colab"
Requires-Dist: pykrige>=1.7; extra == "colab"
Requires-Dist: mapclassify>=2.6; extra == "colab"
Requires-Dist: matplotlib-scalebar>=0.8; extra == "colab"
Requires-Dist: spyndex>=0.5; extra == "colab"
Requires-Dist: pysheds>=0.4; extra == "colab"
Requires-Dist: esda>=2.5; extra == "colab"
Requires-Dist: libpysal>=4.9; extra == "colab"
Requires-Dist: rasterstats>=0.19; extra == "colab"
Requires-Dist: contextily>=1.5; extra == "colab"
Requires-Dist: mapbox-vector-tile>=2.0; extra == "colab"
Requires-Dist: rioxarray>=0.15; extra == "colab"
Requires-Dist: pyarrow>=14.0; extra == "colab"
Requires-Dist: osmnx>=1.9; extra == "colab"
Requires-Dist: fiona>=1.9; extra == "colab"
Dynamic: license-file

[![Downloads](https://img.shields.io/badge/downloads-total-green?logo=pypi&logoColor=white)](https://pepy.tech/projects/notlang)
[![Monthly Downloads](https://img.shields.io/badge/dynamic/json?url=https://pypistats.org/api/packages/notlang/recent&query=$.data.last_month&label=downloads&color=blue&logo=pypi&logoColor=white)](https://pypistats.org/packages/notlang)
[![Socket](https://img.shields.io/badge/socket-security-brightgreen?logo=socket&logoColor=white)](https://badge.socket.dev/pypi/package/notlang/0.9.25?artifact_id=tar-gz)
[![Docs](https://img.shields.io/badge/docs-passing-brightgreen?logo=readthedocs&logoColor=white)](https://docs.notgis.top)
[![License](https://img.shields.io/badge/License-MIT-yellow.svg?logo=open-source-initiative&logoColor=white)](https://pypi.org/project/notlang/)
[![PyPI](https://img.shields.io/pypi/v/notlang.svg?label=pypi&color=orange&logo=pypi&logoColor=white)](https://pypi.org/project/notlang/)
[![Deps.dev](https://img.shields.io/badge/deps.dev-notlang-blue?logo=google&logoColor=white)](https://deps.dev/pypi/notlang)
[![Python](https://img.shields.io/pypi/pyversions/notlang.svg?logo=python&logoColor=white)](https://pypi.org/project/notlang/)

# notLang

**A simple scripting language for GIS and geospatial analysis.**

notLang is a domain-specific language (DSL) built on Python, with English and
Uzbek messages. It brings vector/raster GIS analysis, satellite data (Google
Earth Engine, Copernicus/Sentinel Hub, NASA GIBS, WorldClim), spatial statistics
(Moran's I, LISA, DBSCAN), road-network analysis (OpenStreetMap/osmnx) and 160+
other commands together in one plain syntax.

| | |
|---|---|
| 🌐 **Website** | [notgis.top](https://notgis.top/) |
| 📚 **Documentation** | [docs.notgis.top](https://docs.notgis.top) |
| ▶️ **Playground** (in your browser) | [play.notgis.top](https://play.notgis.top) |
| 💻 **GitHub** | [github.com/notGIS/notlang](https://github.com/notGIS/notlang) |
| 🧩 **VS Code extension** | [Marketplace: notlang.notlang](https://marketplace.visualstudio.com/items?itemName=notlang.notlang) |

```
load "area.geojson" as a
buffer a 500 -> buf
connect gee
get "COPERNICUS/S2_SR_HARMONIZED" date "2026-06-01" "2026-06-30" bbox buf cloud_mask index "NDVI(B8,B4)" -> ndvi
zonal_stats ndvi with a stats "mean,max" -> result
table result to "report.html"
```

## Installation

```bash
pip install notlang[full]
```

For a minimal install: `pip install notlang`. Optional features (GEE, 3D,
hydrology, ...) are added through extras when you need them, for example
`pip install notlang[gee,cartography]`.

Requires **Python 3.9 or newer**.

| Extra | Adds |
|---|---|
| `full` | Almost everything below (recommended) |
| `colab` | A light bundle for Colab (does not re-download packages Colab already has) |
| `gee` | Google Earth Engine |
| `jupyter` | `%load_ext notlang`, ipyleaflet widgets |
| `webmap`, `threed` | Interactive maps (folium); 3D (plotly, pyvista) |
| `spectral`, `hydrology`, `interpolation` | Spectral indices; hydrology; kriging |
| `spatial-stats`, `timeseries`, `network` | Moran/LISA/DBSCAN; time series; OSM networks |
| `cartography`, `cartography-extra`, `parquet`, `vector-io` | Map decorations; zonal stats, static basemaps (incl. OpenFreeMap); Parquet; Fiona |

### Windows (CMD / PowerShell)

```powershell
py -m venv .venv
.venv\Scripts\activate
pip install notlang[full]
notlang --version
```

If the `notlang` command is "not found" (the Scripts folder is not on PATH), run
it through Python — the result is identical:

```powershell
python -m notlang script.ntl
```

### Google Colab

The easiest way in Colab is the `colab` extra. It adds nearly all features
(GEE, hydrology, interpolation, network analysis, ...) without re-downloading the
heavy packages Colab already ships (ipython, plotly, scikit-learn, xarray,
folium) or the 3D stack (pyvista/vtk/trame):

```python
!pip install -q notlang[colab]
```

If you need 3D visualization (`show3d`), add it separately:
`!pip install -q notlang[threed]`.

## Usage

```bash
notlang                  # interactive mode (REPL)
notlang script.ntl       # run a script file
notlang init project     # create a new project template
notlang --version        # version
notlang --about          # about the author/project
notlang --lang uz ...    # message language: en (default) or uz
python -m notlang ...    # all of the above, works without PATH too
```

In Jupyter / Google Colab:

```python
%load_ext notlang
```
```
%%notlang
load "area.geojson" as a
info a
webmap a
```

A Python variable from the notebook can be used inside a string as `"$name"`
(only in `%%notlang`):

```python
path = "area.geojson"
```
```
%%notlang
load "$path" as a
```

You can also use it directly from Python:

```python
from notlang import Interpreter
it = Interpreter()
for message in it.run_iter('load "area.geojson" as a\nbuffer a 500 -> b'):
    print(message)
gdf = it.variables["b"].data      # geopandas.GeoDataFrame
```

### Buffers

Distances are in metres (geographic CRS such as EPSG:4326 are buffered in an
automatically chosen UTM zone and returned in the original CRS).

```
buffer a 500 -> b                      # feature + outer buffer (default)
buffer a 500 outer -> b                # outer ring only
buffer a 500 inner -> b                # inner ring only (polygons)
buffer a 500 both -> b                 # both sides: 500 m inside and 500 m outside
buffer a 500 both to "b.geojson" -> b  # buffer and save to GeoJSON in one step
show a, b
```

### Basemaps

`show` and `webmap` accept `basemap "<name>"`:

| Name | Source |
|---|---|
| `street` / `osm`, `light`, `dark`, `topo`, `satellite` | Raster tiles (OpenStreetMap, CARTO, OpenTopoMap, Esri) |
| `bright`, `liberty`, `positron`, `ofm_dark` | [OpenFreeMap](https://openfreemap.org) vector tiles — free, no API key |

OpenFreeMap needs `pip install mapbox-vector-tile` for static `show` images
(included in the `cartography-extra` and `full` extras).

### Language

Messages are English by default. Use `language "uz"` inside a script, `--lang uz`
on the command line, or the `NOTLANG_LANG=uz` environment variable to switch to
Uzbek.

## Features

- **Vector/raster GIS**: buffer (outer / inner / both), clip, zonal statistics, reclassification, hydrology, interpolation (IDW/kriging)
- **Satellite platforms**: Google Earth Engine (server-side cloud masking, index calculation, Drive/Asset export), Copernicus/Sentinel Hub (6 collections, Statistical API), NASA GIBS, STAC
- **Climate data**: WorldClim (averages, historical, CMIP6 future projections)
- **Spatial statistics**: Moran's I, LISA, DBSCAN, K-Means, hotspots (Getis-Ord Gi*)
- **Road networks**: via OpenStreetMap (osmnx) — download, routing, no API key
- **Other open sources**: GADM, Natural Earth, GBIF, USGS earthquakes, NASA POWER, SoilGrids, OpenAerialMap, Microsoft Building Footprints, and more
- **Visualization**: static maps, interactive web maps (widget in Jupyter, standalone HTML elsewhere), 3D views, charts, OpenFreeMap / OSM / CARTO basemaps
- **Bilingual**: English and Uzbek messages
- **Safe formulas**: `bandmath` and `filter ... where` expressions are restricted (arithmetic and comparisons only) — arbitrary Python code is never executed
- **Versioning**: with `versioning "on"`, saved files are never overwritten; each one is saved with a timestamp

## Documentation

Full guides (Colab, Windows CMD/PowerShell, GEE, Copernicus, open APIs and new
commands) are at **[docs.notgis.top](https://docs.notgis.top)**. You can also try
notLang right in your browser at **[play.notgis.top](https://play.notgis.top)**.
The source code is on [GitHub](https://github.com/notGIS/notlang).

## Editor support

**VS Code** — the official **[notLang extension](https://marketplace.visualstudio.com/items?itemName=notlang.notlang)**
(v0.9.26): syntax highlighting, IntelliSense (160+ commands), 34 snippets, run a
script with `Ctrl+Shift+Enter`, a REPL, and results (webmap, 3D, charts) opened
automatically inside VS Code. It finds notLang by itself (venv, `notlang` or
`python -m notlang`), on Windows too. Search for "notLang" in the Marketplace or
install the `.vsix` file (works in Cursor as well). The `notlang.language`
setting (`en` / `uz`) switches the extension's messages.

Syntax highlighting, completions and snippets are also available for
**Sublime Text** and **Notepad++**.

## Author

**Xushnudbek Rahimberganov**
Website: https://notgis.top
Email: notgis@proton.me

## License

MIT
