Metadata-Version: 2.4
Name: egygeo
Version: 1.3.1
Summary: A Python package for Egyptian governorate centroids, boundaries, reverse geocoding, and map visualization.
Author: Sara Habib
Author-email: sara.habib48@gmail.com
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests
Requires-Dist: shapely
Provides-Extra: map
Requires-Dist: folium; extra == "map"
Provides-Extra: plotly
Requires-Dist: plotly>=5.24; extra == "plotly"
Dynamic: author
Dynamic: author-email
Dynamic: description
Dynamic: description-content-type
Dynamic: license-file
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: summary

# EGYGEO

EGYGEO is a Python package for Egypt’s 27 governorates. It lets you look up each governorate’s centroid coordinates by English or Arabic name, resolve any latitude/longitude to the governorate that contains it using real administrative borders, and retrieve GeoJSON polygons for mapping or analysis.

Use it when you need to:

- **Look up a point** — get the latitude/longitude centroid of a governorate by English or Arabic name (`get_coordinates`)
- **Reverse-geocode a location** — given any lat/lon inside Egypt, find which governorate it falls in using real borders, not just the nearest city center (`get_name`)
- **Get border outlines** — retrieve GeoJSON polygons for mapping, analysis, or export (`get_boundary`)
- **Get shape + metadata together** — return a full GeoJSON Feature with English/Arabic names, id, and centroid (`as_feature=True` or `geometry_type="feature"`)
- **List all governorates** — iterate English and Arabic names programmatically (`list_governorates`)
- **Draw interactive maps** — plot a governorate border (and optional centroid marker) as HTML with Folium (`draw_governorate`)

## Installation

```bash
pip install egygeo
```

For map drawing support:

```bash
pip install egygeo[map]
```

For the interactive Plotly showcase:

```bash
pip install egygeo[plotly]
```

## Interactive showcase (Plotly)

![EGYGEO Plotly map of Egypt's 27 governorates](docs/plotly_showcase.png)

Generate a browser map of all 27 governorate borders:

```bash
pip install -e ".[plotly]"
python examples/plotly_showcase.py
```

Open `examples/output/egygeo_plotly_showcase.html`. Hover a governorate for its English and Arabic name.

## Usage

### Get a governorate centroid

Returns a `(latitude, longitude)` tuple, or `()` if the name is not found.

```python
from egygeo import get_coordinates

latitude, longitude = get_coordinates("Cairo")
print(f"Cairo centroid: {latitude}, {longitude}")

# Arabic names work too
latitude, longitude = get_coordinates("القاهرة")
```

### Get a governorate border

By default returns the GeoJSON **geometry** only (the outline).  
Pass `as_feature=True` to also include names, id, and centroid (see [Return types and parameters](#return-types-and-parameters)).

```python
from egygeo import get_boundary

cairo_border = get_boundary("Cairo")
# {"type": "Polygon", "coordinates": [...]}

cairo_feature = get_boundary("Cairo", as_feature=True)
# {"type": "Feature", "properties": {...}, "geometry": {...}}
```

### Reverse lookup — any point inside Egypt

`get_name` uses point-in-polygon against real governorate borders, so any coordinate inside a governorate works (not just centroids).

Returns a dict with `english`, `arabic`, and `id` keys, or `None` if the point is outside Egypt.

```python
from egygeo import get_name

# Pyramids of Giza area
result = get_name(29.9792, 31.1342)
print(result["english"])  # Giza
print(result["arabic"])   # الجيزة

# Downtown Cairo
result = get_name(30.0444, 31.2357)
print(result["english"])  # Cairo

# Returns None if the point is outside Egypt
result = get_name(40.7128, -74.0060)
print(result)  # None
```

### Draw a governorate on a map

Returns a Folium `Map` object. Saves an HTML file when `output_path` is provided. Requires `egygeo[map]`.

```python
from egygeo import draw_governorate

draw_governorate("Alexandria", output_path="alexandria.html")
draw_governorate("Cairo", output_path="cairo.html", fill_color="#e74c3c")
```

### List all governorates

Returns a list of dicts with `english`, `arabic`, and `id` keys.

```python
from egygeo import list_governorates

for governorate in list_governorates():
    print(governorate["english"], governorate["arabic"])
```

### Unified geometry access

`get_geometry` is one function that can return a point, polygon, or full feature depending on `geometry_type` (see below).

```python
from egygeo import get_geometry

point = get_geometry("Alexandria", geometry_type="point")
polygon = get_geometry("Alexandria", geometry_type="polygon")
feature = get_geometry("Alexandria", geometry_type="feature")
```

## Return types and parameters

### Quick reference

| Function | Returns |
|----------|---------|
| `get_coordinates(name)` | `(latitude, longitude)` tuple, or `()` if not found |
| `get_name(lat, lon)` | `{"english": str, "arabic": str, "id": int}` if inside Egypt, otherwise `None` |
| `get_boundary(name)` | GeoJSON **geometry** dict (`Polygon` or `MultiPolygon`), or `None` if not found |
| `get_boundary(name, as_feature=True)` | GeoJSON **Feature** dict (geometry + properties), or `None` if not found |
| `get_geometry(name, geometry_type=...)` | Point, polygon, or feature — depends on `geometry_type` |
| `list_governorates()` | List of `{"english": str, "arabic": str, "id": int}` |
| `draw_governorate(...)` | Folium `Map` object (also saves HTML when `output_path` is set) |

### `as_feature` (`get_boundary`)

Controls whether you get only the border outline, or the outline plus metadata.

| Value | What you get |
|-------|----------------|
| `False` (default) | Geometry only: `{"type": "Polygon"\|"MultiPolygon", "coordinates": [...]}` |
| `True` | Full GeoJSON Feature: geometry **and** `properties` (`Subdivision_en`, `Subdivision_ar`, `id`, `centroid`) |

Use `as_feature=False` when you only need the shape (drawing, spatial checks, export).  
Use `as_feature=True` when you also need the governorate name, Arabic name, id, or centroid along with the border.

```python
geometry = get_boundary("Cairo")
# Shape only

feature = get_boundary("Cairo", as_feature=True)
```

Example of what `feature` looks like (coordinates shortened for readability; the real border has many more points):

```python
{
  "type": "Feature",
  "properties": {
    "id": 6,
    "Subdivision_en": "Cairo",
    "Subdivision_ar": "القاهرة",
    "centroid": [31.2357257, 30.0443879]  # [longitude, latitude]
  },
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [31.8367932, 30.3209168],
        [31.630124, 30.1979663],
        [31.5924734, 30.1721293],
        # ... more [longitude, latitude] pairs ...
      ]
    ]
  }
}
```

Access the fields like this:

```python
print(feature["properties"]["Subdivision_en"])  # Cairo
print(feature["properties"]["Subdivision_ar"])  # القاهرة
print(feature["geometry"]["type"])              # Polygon or MultiPolygon
```

### `geometry_type` (`get_geometry`)

Chooses which form of data to return. It does not create a new data source — it wraps the same helpers as above.

| `geometry_type` | Equivalent to | Returns |
|-----------------|---------------|---------|
| `"point"` (default) | `get_coordinates(name)` | Centroid as `(latitude, longitude)` |
| `"polygon"` | `get_boundary(name)` | Border GeoJSON geometry only |
| `"feature"` | `get_boundary(name, as_feature=True)` | Full GeoJSON Feature (geometry + properties) |

```python
from egygeo import get_geometry

# Centroid
lat, lon = get_geometry("Alexandria", geometry_type="point")

# Border outline only
polygon = get_geometry("Alexandria", geometry_type="polygon")
# {"type": "Polygon", "coordinates": [...]}

# Border + metadata
feature = get_geometry("Alexandria", geometry_type="feature")
# {"type": "Feature", "properties": {...}, "geometry": {...}}
```

Any other `geometry_type` value raises `ValueError`.

## Name matching

Governorate names can be provided in English or Arabic. Common alternate spellings from other datasets are also supported:

- `Cairo`, `Al Qahirah`, `القاهرة`
- `Alexandria`, `Al Iskandariyah`, `الإسكندرية`
- `Sharqia`, `Al Sharqia`, `الشرقية`
- `Kafr El Sheikh`, `Kafr el-Sheikh`, `كفر الشيخ`

## Data

Boundary polygons are sourced from [geoBoundaries](https://www.geoboundaries.org/) (CC BY 4.0 / ODbL) and normalized to use consistent `Subdivision_en` and `Subdivision_ar` property names across the package.
