{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "62359e08-cf80-4210-a30c-f450000e65b9",
   "metadata": {},
   "source": [
    "# ArcGIS\n",
    "\n",
    "This notebook demonstrates the use of the `langchain.document_loaders.ArcGISLoader` class.\n",
    "\n",
    "You will need to install the ArcGIS API for Python `arcgis` and, optionally, `bs4.BeautifulSoup`.\n",
    "\n",
    "You can use an `arcgis.gis.GIS` object for authenticated data loading, or leave it blank to access public data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b782cab5-0584-4e2a-9073-009fb8dc93a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.document_loaders import ArcGISLoader\n",
    "\n",
    "url = \"https://maps1.vcgov.org/arcgis/rest/services/Beaches/MapServer/7\"\n",
    "loader = ArcGISLoader(url)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "aa3053cf-4127-43ea-bf56-e378b348091f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 2.37 ms, sys: 5.83 ms, total: 8.19 ms\n",
      "Wall time: 1.05 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "docs = loader.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a2444519-9117-4feb-8bb9-8931ce286fa5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'accessed': '2023-09-13T19:58:32.546576+00:00Z',\n",
       " 'name': 'Beach Ramps',\n",
       " 'url': 'https://maps1.vcgov.org/arcgis/rest/services/Beaches/MapServer/7',\n",
       " 'layer_description': '(Not Provided)',\n",
       " 'item_description': '(Not Provided)',\n",
       " 'layer_properties': {\n",
       "   \"currentVersion\": 10.81,\n",
       "   \"id\": 7,\n",
       "   \"name\": \"Beach Ramps\",\n",
       "   \"type\": \"Feature Layer\",\n",
       "   \"description\": \"\",\n",
       "   \"geometryType\": \"esriGeometryPoint\",\n",
       "   \"sourceSpatialReference\": {\n",
       "     \"wkid\": 2881,\n",
       "     \"latestWkid\": 2881\n",
       "   },\n",
       "   \"copyrightText\": \"\",\n",
       "   \"parentLayer\": null,\n",
       "   \"subLayers\": [],\n",
       "   \"minScale\": 750000,\n",
       "   \"maxScale\": 0,\n",
       "   \"drawingInfo\": {\n",
       "     \"renderer\": {\n",
       "       \"type\": \"simple\",\n",
       "       \"symbol\": {\n",
       "         \"type\": \"esriPMS\",\n",
       "         \"url\": \"9bb2e5ca499bb68aa3ee0d4e1ecc3849\",\n",
       "         \"imageData\": \"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAJJJREFUOI3NkDEKg0AQRZ9kkSnSGBshR7DJqdJYeg7BMpcS0uQWQsqoCLExkcUJzGqT38zw2fcY1rEzbp7vjXz0EXC7gBxs1ABcG/8CYkCcDqwyLqsV+RlV0I/w7PzuJBArr1VB20H58Ls6h+xoFITkTwWpQJX7XSIBAnFwVj7MLAjJV/AC6G3QoAmK+74Lom04THTBEp/HCSc6AAAAAElFTkSuQmCC\",\n",
       "         \"contentType\": \"image/png\",\n",
       "         \"width\": 12,\n",
       "         \"height\": 12,\n",
       "         \"angle\": 0,\n",
       "         \"xoffset\": 0,\n",
       "         \"yoffset\": 0\n",
       "       },\n",
       "       \"label\": \"\",\n",
       "       \"description\": \"\"\n",
       "     },\n",
       "     \"transparency\": 0,\n",
       "     \"labelingInfo\": null\n",
       "   },\n",
       "   \"defaultVisibility\": true,\n",
       "   \"extent\": {\n",
       "     \"xmin\": -81.09480168806815,\n",
       "     \"ymin\": 28.858349245353473,\n",
       "     \"xmax\": -80.77512908572814,\n",
       "     \"ymax\": 29.41078388840041,\n",
       "     \"spatialReference\": {\n",
       "       \"wkid\": 4326,\n",
       "       \"latestWkid\": 4326\n",
       "     }\n",
       "   },\n",
       "   \"hasAttachments\": false,\n",
       "   \"htmlPopupType\": \"esriServerHTMLPopupTypeNone\",\n",
       "   \"displayField\": \"AccessName\",\n",
       "   \"typeIdField\": null,\n",
       "   \"subtypeFieldName\": null,\n",
       "   \"subtypeField\": null,\n",
       "   \"defaultSubtypeCode\": null,\n",
       "   \"fields\": [\n",
       "     {\n",
       "       \"name\": \"OBJECTID\",\n",
       "       \"type\": \"esriFieldTypeOID\",\n",
       "       \"alias\": \"OBJECTID\",\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"Shape\",\n",
       "       \"type\": \"esriFieldTypeGeometry\",\n",
       "       \"alias\": \"Shape\",\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"AccessName\",\n",
       "       \"type\": \"esriFieldTypeString\",\n",
       "       \"alias\": \"AccessName\",\n",
       "       \"length\": 40,\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"AccessID\",\n",
       "       \"type\": \"esriFieldTypeString\",\n",
       "       \"alias\": \"AccessID\",\n",
       "       \"length\": 50,\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"AccessType\",\n",
       "       \"type\": \"esriFieldTypeString\",\n",
       "       \"alias\": \"AccessType\",\n",
       "       \"length\": 25,\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"GeneralLoc\",\n",
       "       \"type\": \"esriFieldTypeString\",\n",
       "       \"alias\": \"GeneralLoc\",\n",
       "       \"length\": 100,\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"MilePost\",\n",
       "       \"type\": \"esriFieldTypeDouble\",\n",
       "       \"alias\": \"MilePost\",\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"City\",\n",
       "       \"type\": \"esriFieldTypeString\",\n",
       "       \"alias\": \"City\",\n",
       "       \"length\": 50,\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"AccessStatus\",\n",
       "       \"type\": \"esriFieldTypeString\",\n",
       "       \"alias\": \"AccessStatus\",\n",
       "       \"length\": 50,\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"Entry_Date_Time\",\n",
       "       \"type\": \"esriFieldTypeDate\",\n",
       "       \"alias\": \"Entry_Date_Time\",\n",
       "       \"length\": 8,\n",
       "       \"domain\": null\n",
       "     },\n",
       "     {\n",
       "       \"name\": \"DrivingZone\",\n",
       "       \"type\": \"esriFieldTypeString\",\n",
       "       \"alias\": \"DrivingZone\",\n",
       "       \"length\": 50,\n",
       "       \"domain\": null\n",
       "     }\n",
       "   ],\n",
       "   \"geometryField\": {\n",
       "     \"name\": \"Shape\",\n",
       "     \"type\": \"esriFieldTypeGeometry\",\n",
       "     \"alias\": \"Shape\"\n",
       "   },\n",
       "   \"indexes\": null,\n",
       "   \"subtypes\": [],\n",
       "   \"relationships\": [],\n",
       "   \"canModifyLayer\": true,\n",
       "   \"canScaleSymbols\": false,\n",
       "   \"hasLabels\": false,\n",
       "   \"capabilities\": \"Map,Query,Data\",\n",
       "   \"maxRecordCount\": 1000,\n",
       "   \"supportsStatistics\": true,\n",
       "   \"supportsAdvancedQueries\": true,\n",
       "   \"supportedQueryFormats\": \"JSON, geoJSON\",\n",
       "   \"isDataVersioned\": false,\n",
       "   \"ownershipBasedAccessControlForFeatures\": {\n",
       "     \"allowOthersToQuery\": true\n",
       "   },\n",
       "   \"useStandardizedQueries\": true,\n",
       "   \"advancedQueryCapabilities\": {\n",
       "     \"useStandardizedQueries\": true,\n",
       "     \"supportsStatistics\": true,\n",
       "     \"supportsHavingClause\": true,\n",
       "     \"supportsCountDistinct\": true,\n",
       "     \"supportsOrderBy\": true,\n",
       "     \"supportsDistinct\": true,\n",
       "     \"supportsPagination\": true,\n",
       "     \"supportsTrueCurve\": true,\n",
       "     \"supportsReturningQueryExtent\": true,\n",
       "     \"supportsQueryWithDistance\": true,\n",
       "     \"supportsSqlExpression\": true\n",
       "   },\n",
       "   \"supportsDatumTransformation\": true,\n",
       "   \"dateFieldsTimeReference\": null,\n",
       "   \"supportsCoordinatesQuantization\": true\n",
       " }}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "docs[0].metadata"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9687fb6-5016-41a1-b4e4-7a042aa5291e",
   "metadata": {},
   "source": [
    "### Retrieving Geometries  \n",
    "\n",
    "\n",
    "If you want to retrieve feature geometries, you may do so with the `return_geometry` keyword.\n",
    "\n",
    "Each document's geometry will be stored in its metadata dictionary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "680247b1-cb2f-4d76-ad56-75d0230c2f2a",
   "metadata": {},
   "outputs": [],
   "source": [
    "loader_geom = ArcGISLoader(url, return_geometry=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "93656a43-8c97-4e79-b4e1-be2e4eff98d5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 9.6 ms, sys: 5.84 ms, total: 15.4 ms\n",
      "Wall time: 1.06 s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "docs = loader_geom.load()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "c02eca3b-634a-4d02-8ec0-ae29f5feac6b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'x': -81.01508803280349,\n",
       " 'y': 29.24246579525828,\n",
       " 'spatialReference': {'wkid': 4326, 'latestWkid': 4326}}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "docs[0].metadata['geometry']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "1d132b7d-5a13-4d66-98e8-785ffdf87af0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\"OBJECTID\": 4, \"AccessName\": \"UNIVERSITY BLVD\", \"AccessID\": \"DB-048\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"900 BLK N ATLANTIC AV\", \"MilePost\": 13.74, \"City\": \"DAYTONA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694597536000, \"DrivingZone\": \"BOTH\"}\n",
      "{\"OBJECTID\": 18, \"AccessName\": \"BEACHWAY AV\", \"AccessID\": \"NS-106\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"1400 N ATLANTIC AV\", \"MilePost\": 1.57, \"City\": \"NEW SMYRNA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694600478000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 24, \"AccessName\": \"27TH AV\", \"AccessID\": \"NS-141\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"3600 BLK S ATLANTIC AV\", \"MilePost\": 4.83, \"City\": \"NEW SMYRNA BEACH\", \"AccessStatus\": \"CLOSED FOR HIGH TIDE\", \"Entry_Date_Time\": 1694619363000, \"DrivingZone\": \"BOTH\"}\n",
      "{\"OBJECTID\": 26, \"AccessName\": \"SEABREEZE BLVD\", \"AccessID\": \"DB-051\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"500 BLK N ATLANTIC AV\", \"MilePost\": 14.24, \"City\": \"DAYTONA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694597536000, \"DrivingZone\": \"BOTH\"}\n",
      "{\"OBJECTID\": 30, \"AccessName\": \"INTERNATIONAL SPEEDWAY BLVD\", \"AccessID\": \"DB-059\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"300 BLK S ATLANTIC AV\", \"MilePost\": 15.27, \"City\": \"DAYTONA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694598638000, \"DrivingZone\": \"BOTH\"}\n",
      "{\"OBJECTID\": 33, \"AccessName\": \"GRANADA BLVD\", \"AccessID\": \"OB-030\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"20 BLK OCEAN SHORE BLVD\", \"MilePost\": 10.02, \"City\": \"ORMOND BEACH\", \"AccessStatus\": \"4X4 ONLY\", \"Entry_Date_Time\": 1694595424000, \"DrivingZone\": \"BOTH\"}\n",
      "{\"OBJECTID\": 39, \"AccessName\": \"BEACH ST\", \"AccessID\": \"PI-097\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"4890 BLK S ATLANTIC AV\", \"MilePost\": 25.85, \"City\": \"PONCE INLET\", \"AccessStatus\": \"4X4 ONLY\", \"Entry_Date_Time\": 1694596294000, \"DrivingZone\": \"BOTH\"}\n",
      "{\"OBJECTID\": 44, \"AccessName\": \"SILVER BEACH AV\", \"AccessID\": \"DB-064\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"1000 BLK S ATLANTIC AV\", \"MilePost\": 15.98, \"City\": \"DAYTONA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694598638000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 45, \"AccessName\": \"BOTEFUHR AV\", \"AccessID\": \"DBS-067\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"1900 BLK S ATLANTIC AV\", \"MilePost\": 16.68, \"City\": \"DAYTONA BEACH SHORES\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694598638000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 46, \"AccessName\": \"MINERVA RD\", \"AccessID\": \"DBS-069\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"2300 BLK S ATLANTIC AV\", \"MilePost\": 17.52, \"City\": \"DAYTONA BEACH SHORES\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694598638000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 56, \"AccessName\": \"3RD AV\", \"AccessID\": \"NS-118\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"1200 BLK HILL ST\", \"MilePost\": 3.25, \"City\": \"NEW SMYRNA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694600478000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 65, \"AccessName\": \"MILSAP RD\", \"AccessID\": \"OB-037\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"700 BLK S ATLANTIC AV\", \"MilePost\": 11.52, \"City\": \"ORMOND BEACH\", \"AccessStatus\": \"4X4 ONLY\", \"Entry_Date_Time\": 1694595749000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 72, \"AccessName\": \"ROCKEFELLER DR\", \"AccessID\": \"OB-034\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"400 BLK S ATLANTIC AV\", \"MilePost\": 10.9, \"City\": \"ORMOND BEACH\", \"AccessStatus\": \"CLOSED - SEASONAL\", \"Entry_Date_Time\": 1694591351000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 74, \"AccessName\": \"DUNLAWTON BLVD\", \"AccessID\": \"DBS-078\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"3400 BLK S ATLANTIC AV\", \"MilePost\": 20.61, \"City\": \"DAYTONA BEACH SHORES\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694601124000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 77, \"AccessName\": \"EMILIA AV\", \"AccessID\": \"DBS-082\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"3790 BLK S ATLANTIC AV\", \"MilePost\": 21.38, \"City\": \"DAYTONA BEACH SHORES\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694601124000, \"DrivingZone\": \"BOTH\"}\n",
      "{\"OBJECTID\": 84, \"AccessName\": \"VAN AV\", \"AccessID\": \"DBS-075\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"3100 BLK S ATLANTIC AV\", \"MilePost\": 19.6, \"City\": \"DAYTONA BEACH SHORES\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694601124000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 104, \"AccessName\": \"HARVARD DR\", \"AccessID\": \"OB-038\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"900 BLK S ATLANTIC AV\", \"MilePost\": 11.72, \"City\": \"ORMOND BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694597536000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 106, \"AccessName\": \"WILLIAMS AV\", \"AccessID\": \"DB-042\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"2200 BLK N ATLANTIC AV\", \"MilePost\": 12.5, \"City\": \"DAYTONA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694597536000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 109, \"AccessName\": \"HARTFORD AV\", \"AccessID\": \"DB-043\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"1890 BLK N ATLANTIC AV\", \"MilePost\": 12.76, \"City\": \"DAYTONA BEACH\", \"AccessStatus\": \"CLOSED - SEASONAL\", \"Entry_Date_Time\": 1694591351000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 138, \"AccessName\": \"CRAWFORD RD\", \"AccessID\": \"NS-108\", \"AccessType\": \"OPEN VEHICLE RAMP - PASS\", \"GeneralLoc\": \"800 BLK N ATLANTIC AV\", \"MilePost\": 2.19, \"City\": \"NEW SMYRNA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694600478000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 140, \"AccessName\": \"FLAGLER AV\", \"AccessID\": \"NS-110\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"500 BLK FLAGLER AV\", \"MilePost\": 2.57, \"City\": \"NEW SMYRNA BEACH\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694600478000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 144, \"AccessName\": \"CARDINAL DR\", \"AccessID\": \"OB-036\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"600 BLK S ATLANTIC AV\", \"MilePost\": 11.27, \"City\": \"ORMOND BEACH\", \"AccessStatus\": \"4X4 ONLY\", \"Entry_Date_Time\": 1694595749000, \"DrivingZone\": \"YES\"}\n",
      "{\"OBJECTID\": 174, \"AccessName\": \"EL PORTAL ST\", \"AccessID\": \"DBS-076\", \"AccessType\": \"OPEN VEHICLE RAMP\", \"GeneralLoc\": \"3200 BLK S ATLANTIC AV\", \"MilePost\": 20.04, \"City\": \"DAYTONA BEACH SHORES\", \"AccessStatus\": \"OPEN\", \"Entry_Date_Time\": 1694601124000, \"DrivingZone\": \"YES\"}\n"
     ]
    }
   ],
   "source": [
    "for doc in docs:\n",
    "    print(doc.page_content)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
