To activate online requests, you need to determine these values:
60 |
61 |
account ID (6 characters)
62 |
credential ID (12 characters)
63 |
public key (44 characters)
64 |
65 |
You can place these values in the configuration file, or you can specify them as arguments during session initialization.
66 | See examples at the bottom of this page.
67 |
This section only refers to your CalTopo account credentials - it does not refer to your external account provider credentials
68 | (Google, Yahoo, MSN, Apple, etc.). This module does not need credentials for your external account provider.
69 |
Your CalTopo account may have multiple sets of credentials. These show up in the ‘Credentials’ section at the bottom
70 | of the ‘Your Account’ dialog.
71 |
To open the ‘Your Account’ dialog, sign in to caltopo.com then click your login ID name, to the right of
72 | ‘Your Data’ near the top right of the web interface. Don’t worry if no credentials are listed yet.
73 |
Each credential has a ‘credential ID’ (the 12-character code shown in the Credentials table),
74 | and a ‘public key’, which takes a bit more work to find.
75 |
Currently, the public key is most easily determined during the process of creating a new credential.
Open a web page to caltopo.com. Make sure you are signed in to your account:
79 | you should see your user name or login name at the top right, to the right of ‘Your Data’.
Open the developer console of your browser and start monitoring network traffic.
83 | For Chrome, use F12 to open Chrome DevTools; network traffic logging should be on when you open DevTools,
84 | as indicated by a red square-in-circle near the top left, which would stop monitoring network traffic
85 | when clicked.
86 |
Type ‘sartopo_python’ or a similar name for ‘Your device will be synced as’. The exact name is not important,
87 | but can help you keep track of credentials in case you have several. Afterwards, the name you enter here will
88 | show up in the Credentials section of the Your Account dialog as above.
89 |
Check the checkbox and click Sync Account. (This should load an error page, which is OK.)
90 |
In the network traffic monitor, you will see many requests. After a few seconds, you can stop or pause
91 | network traffic monitoring to make sure the important entry does not get scrolled away as more new traffic happens.
92 |
In the first few requests, at the top of the list, you should see a request similar to:
93 |
finish-activate?code=........&name=......
94 |
95 |
96 |
Write down or copy the 8-character value after ‘code=’ from that request. This is not the value to put in the
97 | configuration file; you will use it in the next step.
98 |
99 |
In a new browser tab, go to:
100 |
caltopo.com/api/v1/activate?code=<code>
101 |
102 |
103 |
104 |
105 |
106 |
replacing <code> with the 8-character code from the previous step.
107 |
108 |
109 |
This should load a page that looks like the following (possibly all compressed into one line):
Enter the 12-character ‘code’ value as ‘id’ in the configuration file. Enter the 44-character value of ‘key’
133 | as ‘key’ in the configuration file. Enter the 6-character ‘id’ value as ‘accountId’ in the configuration file:
134 |
# sartopo_python config file
135 | # This file contains credentials used to send API map requests
136 | # to sartopo.com. Protect and do not distribute these credentials.
137 | [joe@example.com]
138 | id=XXXXXXXXXXXX
139 | key=xXXXXxXXXXXXXXXxxxXXXXxXxXXXXXXXXXXXX=
140 | accountId=ABC123
141 |
142 |
143 |
144 |
145 |
146 |
Alternately, any of these can be specified as arguments when initializing the session, which will override values
147 | from the configuration file (if any):
148 |
149 |
# to use the config file: specify filename and account name
150 | sts=SartopoSession('sartopo.com',
151 | configpath='../../sts.ini',
152 | account='joe@gmail.com')
153 |
154 | # to use arguments instead of the config file:
155 | sts=SartopoSession('sartopo.com',
156 | id='XXXXXXXXXXXX',
157 | key='xXXXXxXXXXXXXXXxxxXXXXxXxXXXXXXXXXXXX=',
158 | accountId='ABC123')
159 |
160 | # to use the config file, but use arguments to override values from the config file:
161 | sts=SartopoSession('sartopo.com',
162 | configpath='../../sts.ini',
163 | account='joe@gmail.com',
164 | id='XXXXXXXXXXXX',
165 | key='xXXXXxXXXXXXXXXxxxXXXXxXxXXXXXXXXXXXX=',
166 | accountId='ABC123')
167 |
For some property and argument values that are specified as strings, only certain values will be processed correctly.
60 |
These fixed lists of choices are determined by caltopo.com - not by the authors of this module. The lists below are (hopefully) accurate at the time of writing, but, could change at any time.
61 |
The best option is to inspect outgoing network traffic while creating or editing a feature from the web interface with the selection you want.
62 |
63 |
64 |
Marker symbol name
There are well over a hundred available marker symbols. Only a few common ones are listed here. Use the technique above to find the one you want.
65 |
point, c:ring, c:target1, cp, heatsource, clue
66 |
67 |
68 |
69 |
70 |
Line pattern
These formatted strings are too detailed to list here. Use the technique above to find the one you want.
There are two categories of migration that you might be concerned with:
71 |
72 |
1. sartopo_python is changing names to caltopo_python¶
73 |
This module began as ‘sartopo_python’. There are several reasons for changing the module name, including:
74 |
75 |
most of the features in this module are not SAR-specific
76 |
sartopo.com is now effectively the same as caltopo.com; the only difference is the ‘SAR’ vs. ‘Recreation’ mode setting for each map
77 |
caltopo.com has much broader name recognition than sartopo.com outside of the SAR community
78 |
CalTopo is the name of the app; there is no ‘SARTopo app’
79 |
the name of the downloadble server is CalTopo Desktop (formerly SARTopo Offline or CalTopo Offline); there is no ‘SARTopo Desktop’
80 |
81 |
caltopo_python 1.0.x will be identical to sartopo_python 2.0.x.
82 |
sartopo_python will not receive any updates after 2.0.x. That is, there will be no sartopo_python 2.1.0.
83 | Patches / bug fixes to 1.0 / 2.0 will be applied to both packages, but,
84 | minor and major version updates will only be applied to caltopo_python.
85 |
We suggest that you change to caltopo_python as soon as possible. If you are just getting started with sartopo_python, we suggest that you use caltopo_python instead.
86 |
How do I migrate from sartopo_python to caltopo_python?
87 |
88 |
pip install caltopo_python
89 |
import caltopo_python instead of import sartopo_python
90 |
create an instance of CaltopoSession instead of SartopoSession
91 |
92 |
There is no change to class method names or signatures. The class name is the only difference.
93 |
94 |
95 |
2. migrating to sartopo_python 2.0.0 from an earlier version¶
96 |
(or, migrating to caltopo_python 1.0.0 from an earlier version of sartopo_python)
97 |
Some class method names and signatures have changed from earlier versions.
98 |
Several method names now start with an underscore, to indicate that they are not likely to be needed directly
99 | in your downstream code. These ‘internal’ data management and helper methods are normally only called internally
100 | by other class methods.
101 |
They can still be called from your downstream code if there is a specific need, as long as you are fully aware
102 | of their impacts on internal class data - especially the local cache and the threaded queueing operations.
103 |
These previously-non-underscored methods from the latest PyPi version (1.1.2) are now ‘internal’ (e.g. .setupSession is now ._setupSession):
104 |
105 |
._setupSession, ._sendRequest
106 |
107 |
In addition, these previously-non-underscored methods from more recent versions of source code are now ‘internal’:
In general, the changes from the latest PyPi version (1.1.2) are extensive enough that documenting
112 | the differences would not be any more helpful than looking in the Class Reference.
113 |
Changes from more recent versions of source code mainly involve method signatures (argument names, types, and sequences).
114 |
In either case, migrating your code from previous versions may be a fair amount of work, but the new feature set and
115 | forward compatibility should be a good payoff. Use the Examples section of the main page,
116 | and the Class Reference, as your guides.
9 |
10 |
--------------------------------------------------------------------------------
/docs/source/_templates/localtoc.html:
--------------------------------------------------------------------------------
1 | {#
2 | basic/localtoc.html
3 | ~~~~~~~~~~~~~~~~~~~
4 |
5 | Sphinx sidebar template: local table of contents.
6 |
7 | :copyright: Copyright 2007-2024 by the Sphinx team, see AUTHORS.
8 | :license: BSD, see LICENSE for details.
9 | #}
10 | {%- if display_toc %}
11 |
12 |
13 | {{ toc }}
14 |
15 | {%- endif %}
16 |
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # For the full list of built-in configuration values, see the documentation:
4 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
5 |
6 | import os
7 | import sys
8 | sys.path.insert(0, os.path.abspath('../..'))
9 |
10 | # -- Project information -----------------------------------------------------
11 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
12 |
13 | project = 'sartopo_python'
14 | copyright = '2024, Tom Grundy'
15 | author = 'Tom Grundy'
16 | release = '2.0.0'
17 |
18 | # -- General configuration ---------------------------------------------------
19 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
20 |
21 | extensions = [
22 | 'sphinx.ext.autodoc'
23 | ]
24 |
25 | templates_path = ['_templates']
26 | exclude_patterns = []
27 |
28 |
29 |
30 | # -- Options for HTML output -------------------------------------------------
31 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
32 |
33 | html_theme = 'alabaster'
34 | html_logo = '_static/caltopo_python_logo.png'
35 | html_theme_options = {
36 | 'page_width':'85%',
37 | 'sidebar_width':'250px',
38 | 'sidebar_collapse':True,
39 | 'fixed_sidebar':True,
40 | 'logo':'caltopo_python_logo.png'
41 | }
42 | html_static_path = ['_static']
43 | html_sidebars = {
44 | '**': [
45 | 'allpages.html',
46 | 'localtoc.html',
47 | 'searchbox.html'
48 | ]
49 | }
50 |
51 | autoclass_content = 'both'
52 | add_module_names = False
53 | toc_object_entries_show_parents = 'hide'
54 |
--------------------------------------------------------------------------------
/docs/source/credentials.rst:
--------------------------------------------------------------------------------
1 | :tocdepth: 1
2 |
3 | Credentials
4 | ===========
5 |
6 | To activate online requests, you need to determine these values:
7 |
8 | - account ID (6 characters)
9 | - credential ID (12 characters)
10 | - public key (44 characters)
11 |
12 | You can place these values in the configuration file, or you can specify them as arguments during session initialization.
13 | See examples at the bottom of this page.
14 |
15 | This section only refers to your CalTopo account credentials - it does not refer to your external account provider credentials
16 | (Google, Yahoo, MSN, Apple, etc.). **This module does not need credentials for your external account provider.**
17 |
18 | Your CalTopo account may have multiple sets of credentials. These show up in the 'Credentials' section at the bottom
19 | of the 'Your Account' dialog.
20 |
21 | To open the 'Your Account' dialog, sign in to caltopo.com then click your login ID name, to the right of
22 | 'Your Data' near the top right of the web interface. Don't worry if no credentials are listed yet.
23 |
24 | Each credential has a 'credential ID' (the 12-character code shown in the Credentials table),
25 | and a 'public key', which takes a bit more work to find.
26 |
27 | Currently, the public key is most easily determined during the process of creating a new credential.
28 |
29 | To create a new credential and to determine its credential ID and public key, follow these steps (based on the README at |sme-sartopo-mapsrv_link|):
30 |
31 | 1. Open a web page to caltopo.com. Make sure you are signed in to your account:
32 | you should see your user name or login name at the top right, to the right of 'Your Data'.
33 |
34 | 2. In a separate browser tab, go to |activation-link|.
35 | This should show a web page similar to |activation-image_link| from the |desktop-installation_link| instructions. Don't click Sync Account yet.
36 |
37 | 3. Open the developer console of your browser and start monitoring network traffic.
38 | For Chrome, use F12 to open Chrome DevTools; network traffic logging should be on when you open DevTools,
39 | as indicated by a red square-in-circle near the top left, which would stop monitoring network traffic
40 | when clicked.
41 |
42 | 4. Type 'sartopo_python' or a similar name for 'Your device will be synced as'. The exact name is not important,
43 | but can help you keep track of credentials in case you have several. Afterwards, the name you enter here will
44 | show up in the Credentials section of the Your Account dialog as above.
45 |
46 | 5. Check the checkbox and click Sync Account. (This should load an error page, which is OK.)
47 |
48 | 6. In the network traffic monitor, you will see many requests. After a few seconds, you can stop or pause
49 | network traffic monitoring to make sure the important entry does not get scrolled away as more new traffic happens.
50 |
51 | 7. In the first few requests, at the top of the list, you should see a request similar to::
52 |
53 | finish-activate?code=........&name=......
54 |
55 | Write down or copy the 8-character value after 'code=' from that request. This is not the value to put in the
56 | configuration file; you will use it in the next step.
57 |
58 | 8. In a new browser tab, go to::
59 |
60 | caltopo.com/api/v1/activate?code=
61 |
62 | replacing with the 8-character code from the previous step.
63 |
64 | 9. This should load a page that looks like the following (possibly all compressed into one line):
65 |
66 | .. code-block:: json
67 |
68 | {
69 | "code": "XXXXXXXXXXX",
70 | "account": {
71 | "id": "ABC123",
72 | "type": "Feature",
73 | "properties": {
74 | "subscriptionExpires": 1554760038,
75 | "subscriptionType": "pro-1",
76 | "subscriptionRenew": true,
77 | "subscriptionStatus": "active",
78 | "title": "......@example",
79 | "class": "UserAccount",
80 | "updated": 1554760038,
81 | "email": "......@example.com"
82 | }
83 | },
84 | "key": "xXXXXxXXXXXXXXXxxxXXXXxXxXXXXXXXXXXXX="
85 | }
86 |
87 | 10. Enter the 12-character 'code' value as 'id' in the configuration file. Enter the 44-character value of 'key'
88 | as 'key' in the configuration file. Enter the 6-character 'id' value as 'accountId' in the configuration file::
89 |
90 | # sartopo_python config file
91 | # This file contains credentials used to send API map requests
92 | # to sartopo.com. Protect and do not distribute these credentials.
93 | [joe@example.com]
94 | id=XXXXXXXXXXXX
95 | key=xXXXXxXXXXXXXXXxxxXXXXxXxXXXXXXXXXXXX=
96 | accountId=ABC123
97 |
98 | Alternately, any of these can be specified as arguments when initializing the session, which will override values
99 | from the configuration file (if any):
100 |
101 | .. code-block:: python
102 |
103 | # to use the config file: specify filename and account name
104 | sts=SartopoSession('sartopo.com',
105 | configpath='../../sts.ini',
106 | account='joe@gmail.com')
107 |
108 | # to use arguments instead of the config file:
109 | sts=SartopoSession('sartopo.com',
110 | id='XXXXXXXXXXXX',
111 | key='xXXXXxXXXXXXXXXxxxXXXXxXxXXXXXXXXXXXX=',
112 | accountId='ABC123')
113 |
114 | # to use the config file, but use arguments to override values from the config file:
115 | sts=SartopoSession('sartopo.com',
116 | configpath='../../sts.ini',
117 | account='joe@gmail.com',
118 | id='XXXXXXXXXXXX',
119 | key='xXXXXxXXXXXXXXXxxxXXXXxXxXXXXXXXXXXXX=',
120 | accountId='ABC123')
121 |
122 | .. |activation-link| raw:: html
123 |
124 | https://caltopo.com/app/activate/offline?redirect=localhost
125 |
126 | .. |activation-image_link| raw:: html
127 |
128 | the one used during CalTopo Desktop activation
129 |
130 | .. |desktop-installation_link| raw:: html
131 |
132 | CalTopo Desktop Installation
133 |
134 | .. |sme-sartopo-mapsrv_link| raw:: html
135 |
136 | https://github.com/elliottshane/sme-sartopo-mapsrv
--------------------------------------------------------------------------------
/docs/source/fixedChoices.rst:
--------------------------------------------------------------------------------
1 | Fixed choices
2 | -------------
3 | For some property and argument values that are specified as strings, only certain values will be processed correctly.
4 |
5 | These fixed lists of choices are determined by caltopo.com - not by the authors of this module. The lists below are (hopefully) accurate at the time of writing, but, could change at any time.
6 |
7 | The best option is to inspect outgoing network traffic while creating or editing a feature from the web interface with the selection you want.
8 |
9 | - Marker symbol name
10 | There are well over a hundred available marker symbols. Only a few common ones are listed here. Use the technique above to find the one you want.
11 |
12 | point, c:ring, c:target1, cp, heatsource, clue
13 |
14 | - Line pattern
15 | These formatted strings are too detailed to list here. Use the technique above to find the one you want.
16 |
17 | - Feature class
18 | Shape, Marker, AppTrack, LiveTrack, Folder, MapMediaObject, OperationalPeriod, Assignment, Clue, Resource, SmsLocationRequest
19 | - NOTE: Polygons and Lines are both part of the 'Shape' feature class, but are differentiated by the 'Geometry type' of 'Polygon' vs. 'LineString'.
20 |
21 | - Assignment priority
22 | HIGH, MEDIUM, LOW
23 |
24 | - Assignment POD (Responsive, Unresponsive, Clue)
25 | HIGH, MEDIUM, LOW
26 |
27 | - Assignment status
28 | DRAFT, PREPARED, INPROGRESS, COMPLETED
29 |
30 | - Assignment resource type
31 |
32 | GROUND, GROUND_1, GROUND_2, GROUND_3, DOG, DOG_TRAIL, DOG_AREA, DOG_HRD, OHV, BIKE, WATER, MOUNTED, AIR
33 |
34 | - NOTE: Underscores are used in the actual property values, but the web interface will display hyphens instead of underscores.
--------------------------------------------------------------------------------
/docs/source/index.rst:
--------------------------------------------------------------------------------
1 | .. sartopo_python documentation master file, created by
2 | sphinx-quickstart on Fri May 17 19:27:57 2024.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | :tocdepth: 1
7 |
8 | .. .. toctree::
9 | .. .. :maxdepth: 2
10 | .. :caption: Other pages:
11 |
12 | .. credentials
13 | .. sartopo_python
14 |
15 | sartopo_python
16 | ==========================================
17 |
18 | CalTopo is a very popular web-browser-based and smartphone-app-based mapping tool. SARTopo is a mostly-obsolete
19 | name that refers to a set of Search-And-Rescue-specific features inside the CalTopo tool. See |caltopo_link| and |training_link|.
20 |
21 | Being a web-based tool, CalTopo / SARTopo uses a web API to accomplish most user actions. The API is not currently documented or developed for general public use, and could change at any time.
22 |
23 | This module provides a 'session' object which manages a data connection to a hosted map, and provides several wrapper methods and convenience methods that make calls to the non-publicized CalTopo API.
24 |
25 | **This third-party module is not written or maintained by CalTopo LLC or the authors of caltopo.com or sartopo.com.**
26 |
27 | **DISCLAIMER: This module can edit and delete CalTopo / SARTopo map features. At the time of this module's publication, CalTopo and SARTopo do not have any 'undo' capability.**
28 | Only you can take steps to prevent loss of map data due to use of this module - whether due to accidental misuse, or due to an unexpected bug in the module. You should always consider exporting a full GeoJSON from your map before using this code.
29 |
30 | Categories of provided class methods:
31 | - account data access
32 | - feature creation
33 | - feature editing
34 | - feature querying
35 | - feature deletion
36 | - geometry operations
37 |
38 | See the `SartopoSession Class Reference <./sartopo_python.html>`_ for details.
39 |
40 | Installation
41 | ============
42 | Install this package in the usual manner:
43 |
44 | .. code-block:: python
45 |
46 | pip install sartopo_python
47 |
48 | To activate online requests, you will need to determine your account ID, credential ID, and public key. See details at the :doc:`credentials` page.
49 |
50 | **NOTE: sartopo_python is changing names to caltopo_python.**
51 | caltopo_python 1.0.x will be identical to sartopo_python 2.0.x.
52 |
53 | We suggest that you change to caltopo_python as soon as possible. If you are just getting started with sartopo_python, we suggest that you use caltopo_python instead.
54 |
55 | For more information, see the :doc:`migration` page.
56 |
57 | Key Features
58 | ===============
59 |
60 | Internet or locally-hosted
61 | --------------------------
62 | In addition to the standard caltopo.com or sartopo.com web interface, CalTopo provides a downloadable local HTTP server
63 | called CalTopo Desktop (formerly CalTopo Offline or SARTopo Offline). This module works with either solution.
64 |
65 | Configuration file
66 | ------------------
67 | User account details, including the authentication public key (used to generate signed requests, as required by caltopo.com and sartopo.com),
68 | are kept in a local configuration file that you control. A template configuration file comes with this package.
69 |
70 | See the bottom of the Examples section for configuration file examples. See the :doc:`credentials` page for details on authentication.
71 |
72 | Mapless session
73 | ---------------
74 | You may want to initialize the session without specifying a map, e.g. if you need to start
75 | by checking the list of available maps before you know which map to open.
76 |
77 | You can open a 'mapless' session by simply omitting the mapID argument when you initialize the session. In that case, you can
78 | open a map later, within the same session, with .openMap().
79 |
80 | Any of the 'account data access methods' will work in a mapless session.
81 | Most of the other class methods require an open map, so will fail with an error message if called in a mapless session.
82 |
83 | Local cache
84 | -----------
85 | If the session is associated with a hosted map, this module will keep a local cache of the entire map data structure. This reduces
86 | the number of web requests needed, which reduces the time taken for most tasks.
87 |
88 | Sync with callbacks
89 | -------------------
90 | To keep the local cache in sync with the hosted map, this module automatically requests and processes updates from the host at the specified sync interval.
91 |
92 | This sync procedure is done in a background thread, so that it doesn't delay or interfere with your code. Sync can be paused or disabled if needed.
93 |
94 | You can also write callback functions that will be called whenever map data changes are found during sync.
95 |
96 | Examples
97 | ========
98 |
99 | Opening a session
100 | -----------------
101 |
102 | .. code-block:: python
103 |
104 | from sartopo_python import SartopoSession
105 |
106 | # open an online session and map
107 | sts=SartopoSession('caltopo.com','A1B2C',
108 | configpath='../../sts.ini',
109 | account='joe@domain.com')
110 |
111 | # open a CalTopo Desktop session and map
112 | sts=SartopoSession('localhost:8080','A1B2C',
113 | configpath='../../sts.ini',
114 | account='joe@domain.com')
115 |
116 | # open an online mapless session
117 | sts=SartopoSession('caltopo.com',
118 | configpath='../../sts.ini',
119 | account='joe@domain.com')
120 |
121 | # open a map, for a session that was initially mapless
122 | sts.openMap('A1B2C')
123 |
124 | Syncing and callbacks
125 | ---------------------
126 |
127 | .. code-block:: python
128 |
129 | # define callback functions
130 | def pucb(*args):
131 | print('Property Updated: pucb called with args '+str(args))
132 |
133 | def gucb(*args):
134 | print('Geometry Updated: gucb called with args '+str(args))
135 |
136 | def nfcb(*args):
137 | print('New Feature: nfcb called with args '+str(args))
138 |
139 | def dfcb(*args):
140 | print('Deleted Feature: dfcb called with args '+str(args))
141 |
142 | # open a session, connecting to the defined callbacks;
143 | # syncing is enabled by default, since the 'sync' argument defaults to True
144 | sts=SartopoSession('caltopo.com','A1B2C',
145 | configpath='../../sts.ini',
146 | account='joe@domain.com',
147 | propUpdateCallback=pucb,
148 | geometryUpdateCallback=gucb,
149 | newFeatureCallback=nfcb,
150 | deletedFeatureCallback=dfcb)
151 |
152 | Getting map data and account data
153 | ---------------------------------
154 |
155 | .. code-block:: python
156 |
157 | # get the personal map list (for joe@domain.com)
158 | sts.getMapList()
159 |
160 | # get the MyTeam map list (assuming joe@domain.com is a member of MyTeam)
161 | sts.getMapList('MyTeam')
162 |
163 | # get a dict of all map lists (for joe@domain.com)
164 | sts.getAllMapLists()
165 |
166 | # get the title of a map (assuming joe@domain.com has access to the map)
167 | sts.getMapTitle('A1B2C')
168 |
169 | # get the list of titles of group accounts of which joe@domain.com is a member
170 | sts.getGroupAccountTitles()
171 |
172 | Adding features
173 | ---------------
174 |
175 | A word on longitude / latitude sequence:
176 |
177 | caltopo.com expects each point of every type of geometry to have longitude first, followed by latutude, e.g. [120,-39].
178 |
179 | While the code will swap coordinates if needed and if detectable (which is only the case for half of the globe), it's best to get in the habit of
180 | specifying points in [lon,lat] sequence. See the *._validatePoints* documentation for details.
181 |
182 | This is opposite of the Marker functions, which call for the latitude argument first.
183 |
184 | .. code-block:: python
185 |
186 | # add a marker
187 | sts.addMarker(39,-120,'MyMarker')
188 |
189 | # add a folder
190 | fid=sts.addFolder('MyFolder')
191 |
192 | # add a marker in the folder
193 | myMarker2=sts.addMarker(39.01,-120.01,'MyMarker2',folderId=fid)
194 |
195 | # add a line
196 | sts.addLine([[39,-120],[39.1,-120.1]],'MyLine')
197 |
198 | # prepare to add a polygon - queue it for later
199 | sts.addPolygon([[39,-120],[39.1,-120.1],[39.1,-120]],'MyPolygon',queue=True)
200 |
201 | # add an Operational Period
202 | op1=sts.addOperationalPeriod('1')
203 |
204 | # prepare to add a line assignment - queue it for later
205 | aa=sts.addLineAssignment([[39.2,-120],[39.2,-120.1]],
206 | letter='AA',
207 | opId=op1,
208 | resourceType='DOG-TRAIL',
209 | description='FindEm',
210 | queue=True)
211 |
212 | sts.addAreaAssignment([[39.3,-120],[39.4,-120.1],[39.4,-120]],
213 | letter='AB',
214 | number='104',
215 | opId=op1,
216 | resourceType='DOG-AREA',
217 | description='FindEmFirst',
218 | responsivePOD='HIGH',
219 | priority='HIGH')
220 |
221 | # add the queued features now (MyPolygon and AA)
222 | sts.flush()
223 |
224 | Querying and editing features
225 | -----------------------------
226 |
227 | .. code-block:: python
228 |
229 | myMarker=sts.getFeature('Marker','MyMarker')
230 |
231 | sts.editFeature(myMarker['id'],properties={'title','NewTitle'})
232 |
233 | sts.moveMarker(39,-121.5,myMarker['id'])
234 |
235 | sts.editMarkerDescription('New marker description',myMarker['id'])
236 |
237 | Geometry operations
238 | -------------------
239 |
240 | .. code-block:: python
241 |
242 | # assuming all of the named features below have already been drawn
243 |
244 | # cut area assignment AC 103, using line b0
245 | sts.cut('AC 103','b0')
246 |
247 | # cut line a1, using line b1
248 | sts.cut('a1','b1')
249 |
250 | # cut polygon a8, using polygon b8, but do not delete b8 afterwards
251 | sts.cut('a8','b8',deleteCutter=False)
252 |
253 | # arguments are ids instead of entire features
254 | sts.cut(a12['id'],b12['id'])
255 |
256 | # expand polygon a7 to include polygon b7, a.k.a. "a7 = a7 OR b7"
257 | sts.expand('a7','b7')
258 |
259 | # crop line a14 using boundary poygon b14
260 | sts.crop('a14','b14')
261 |
262 | # crop line a15 using boundary polygon b15, with zero oversize
263 | sts.crop('a15','b15',beyond=0)
264 |
265 | Deleting features
266 | -----------------
267 |
268 | .. code-block:: python
269 |
270 | sts.delFeature(aa)
271 |
272 | sts.delMarkers([myMarker,myMarker2])
273 |
274 | Configuration file
275 | ------------------
276 |
277 | .. code-block:: python
278 |
279 | # sartopo_python config file
280 | # This file contains credentials used to send API map requests
281 | # to caltopo.com, sartopo.com, or CalTopo Desktop.
282 | # Protect and do not distribute these credentials.
283 |
284 | [joe@domain.com] # section referenced by 'account' session object attribute / argument
285 | id=A1B2C3D4E5F6 # 12-character credential ID
286 | key=............................................ # 44-character caltopo API key
287 | accountId=A1B2C3 # 6-character account ID
288 |
289 |
290 | .. Indices and tables
291 | .. ==================
292 |
293 | .. * :ref:`genindex`
294 | .. * :ref:`modindex`
295 | .. * :ref:`search`
296 |
297 | .. |caltopo_link| raw:: html
298 |
299 | caltopo.com
300 |
301 | .. |training_link| raw:: html
302 |
303 | training.caltopo.com
304 |
305 |
306 |
--------------------------------------------------------------------------------
/docs/source/migration.rst:
--------------------------------------------------------------------------------
1 | Migration
2 | ==========================================
3 |
4 | There are two categories of migration that you might be concerned with:
5 |
6 | 1. sartopo_python is changing names to caltopo_python
7 | -----------------------------------------------------
8 |
9 | This module began as 'sartopo_python'. There are several reasons for changing the module name, including:
10 |
11 | - most of the features in this module are not SAR-specific
12 | - sartopo.com is now effectively the same as caltopo.com; the only difference is the 'SAR' vs. 'Recreation' mode setting for each map
13 | - caltopo.com has much broader name recognition than sartopo.com outside of the SAR community
14 | - CalTopo is the name of the app; there is no 'SARTopo app'
15 | - the name of the downloadble server is CalTopo Desktop (formerly SARTopo Offline or CalTopo Offline); there is no 'SARTopo Desktop'
16 |
17 | caltopo_python 1.0.x will be identical to sartopo_python 2.0.x.
18 |
19 | sartopo_python will not receive any updates after 2.0.x. That is, there will be no sartopo_python 2.1.0.
20 | Patches / bug fixes to 1.0 / 2.0 will be applied to both packages, but,
21 | minor and major version updates will only be applied to caltopo_python.
22 |
23 | We suggest that you change to caltopo_python as soon as possible. If you are just getting started with sartopo_python, we suggest that you use caltopo_python instead.
24 |
25 | *How do I migrate from sartopo_python to caltopo_python?*
26 |
27 | 1. pip install caltopo_python
28 | 2. import caltopo_python instead of import sartopo_python
29 | 3. create an instance of CaltopoSession instead of SartopoSession
30 |
31 | There is no change to class method names or signatures. The class name is the only difference.
32 |
33 | 2. migrating to sartopo_python 2.0.0 from an earlier version
34 | ------------------------------------------------------------
35 |
36 | (or, migrating to caltopo_python 1.0.0 from an earlier version of sartopo_python)
37 |
38 | Some class method names and signatures have changed from earlier versions.
39 |
40 | Several method names now start with an underscore, to indicate that they are not likely to be needed directly
41 | in your downstream code. These 'internal' data management and helper methods are normally only called internally
42 | by other class methods.
43 |
44 | They can still be called from your downstream code if there is a specific need, as long as you are fully aware
45 | of their impacts on internal class data - especially the local cache and the threaded queueing operations.
46 |
47 | These previously-non-underscored methods from the latest PyPi version (1.1.2) are now 'internal' (e.g. .setupSession is now ._setupSession):
48 |
49 | - ._setupSession, ._sendRequest
50 |
51 | In addition, these previously-non-underscored methods from more recent versions of source code are now 'internal':
52 |
53 | - ._sendUserdata, ._doSync, ._refresh, ._start, ._stop, ._pause, ._resume, ._buffer2, ._intersection2, ._caseMatch, ._twoify, ._fourify, ._removeDuplicatePoints, ._removeSpurs, ._getUsedSuffixList, ._getNextAvailableSuffix, ._getToken
54 |
55 | In general, the changes from the latest PyPi version (1.1.2) are extensive enough that documenting
56 | the differences would not be any more helpful than looking in the Class Reference.
57 |
58 | Changes from more recent versions of source code mainly involve method signatures (argument names, types, and sequences).
59 |
60 | In either case, migrating your code from previous versions may be a fair amount of work, but the new feature set and
61 | forward compatibility should be a good payoff. Use the Examples section of the main page,
62 | and the Class Reference, as your guides.
--------------------------------------------------------------------------------
/docs/source/sartopo_python.rst:
--------------------------------------------------------------------------------
1 | :tocdepth: 3
2 |
3 | sartopo\_python module
4 | ======================
5 |
6 | This module provides one main class: SartopoSession. Class methods are categorized and documented below.
7 |
8 | Downstream code should create and use one instance of this class.
9 |
10 | An exception class is also defined, STSException, which could be thrown during initialization but is not documented here.
11 |
12 | .. see https://stackoverflow.com/a/48682589/3577105 for categorization technique
13 | .. currentmodule:: sartopo_python
14 |
15 | .. autoclass:: SartopoSession
16 |
17 | .. omitting class name from automethod calls, when the section headers are unindented,
18 | .. causes these failures, but, the headers need to be unindented for the TOC to recognize them:
19 | .. WARNING: don't know which module to import for autodocumenting 'openMap' (try placing a "module" or "currentmodule" directive in the document, or giving an explicit module name)
20 |
21 | .. **Session setup methods**
22 | .. -------------------------
23 |
24 | .. automethod:: SartopoSession.openMap
25 |
26 | **Account data access methods**
27 | -------------------------------
28 | These methods may be called from either a mapless or a map-associated session.
29 |
30 | .. automethod:: SartopoSession.getAccountData
31 | .. automethod:: SartopoSession.getMapList
32 | .. automethod:: SartopoSession.getAllMapLists
33 | .. automethod:: SartopoSession.getMapTitle
34 | .. automethod:: SartopoSession.getGroupAccountTitles
35 |
36 | **Feature creation methods**
37 | ----------------------------
38 | Most of these feature creation methods can be used to edit an existing feature,
39 | by specifying the existingId argument. .editFeature is a convenience method
40 | that calls the appropriate .add... method with existingId specified.
41 |
42 | .. automethod:: SartopoSession.addFolder
43 | .. automethod:: SartopoSession.addMarker
44 | .. automethod:: SartopoSession.addLine
45 | .. automethod:: SartopoSession.addPolygon
46 | .. automethod:: SartopoSession.addOperationalPeriod
47 | .. automethod:: SartopoSession.addLineAssignment
48 | .. automethod:: SartopoSession.addAreaAssignment
49 | .. automethod:: SartopoSession.addAppTrack
50 | .. automethod:: SartopoSession.flush
51 |
52 | **Feature query methods**
53 | -------------------------
54 |
55 | .. automethod:: SartopoSession.getFeature
56 | .. automethod:: SartopoSession.getFeatures
57 |
58 | **Feature editing methods**
59 | ---------------------------
60 |
61 | .. automethod:: SartopoSession.editFeature
62 | .. automethod:: SartopoSession.moveMarker
63 | .. automethod:: SartopoSession.editMarkerDescription
64 |
65 | **Feature deletion methods**
66 | ----------------------------
67 |
68 | .. automethod:: SartopoSession.delFeature
69 | .. automethod:: SartopoSession.delFeatures
70 | .. automethod:: SartopoSession.delMarker
71 | .. automethod:: SartopoSession.delMarkers
72 |
73 | **Geometry operation methods**
74 | ------------------------------
75 | These methods use the python |shapely_link| module.
76 |
77 | .. automethod:: SartopoSession.cut
78 | .. automethod:: SartopoSession.expand
79 | .. automethod:: SartopoSession.crop
80 | .. automethod:: SartopoSession.getBounds
81 |
82 | **Internal data management methods**
83 | ------------------------------------
84 | These methods are typically only called internally, from other class methods. They can be called from downstream code if needed, with caution.
85 |
86 | .. automethod:: SartopoSession._setupSession
87 | .. automethod:: SartopoSession._sendUserdata
88 | .. automethod:: SartopoSession._doSync
89 | .. automethod:: SartopoSession._refresh
90 | .. automethod:: SartopoSession.__del__
91 | .. automethod:: SartopoSession._start
92 | .. automethod:: SartopoSession._stop
93 | .. automethod:: SartopoSession._pause
94 | .. automethod:: SartopoSession._resume
95 | .. automethod:: SartopoSession._syncLoop
96 | .. automethod:: SartopoSession._sendRequest
97 | .. automethod:: SartopoSession._delAsync
98 | .. automethod:: SartopoSession._buffer2
99 | .. automethod:: SartopoSession._intersection2
100 |
101 | **Internal helper methods**
102 | ---------------------------
103 | These methods are typically only called internally, from other class methods. They can be called from downstream code if needed, with caution.
104 |
105 | .. automethod:: SartopoSession._caseMatch
106 | .. automethod:: SartopoSession._twoify
107 | .. automethod:: SartopoSession._fourify
108 | .. automethod:: SartopoSession._removeDuplicatePoints
109 | .. automethod:: SartopoSession._removeSpurs
110 | .. automethod:: SartopoSession._getUsedSuffixList
111 | .. automethod:: SartopoSession._getNextAvailableSuffix
112 | .. automethod:: SartopoSession._validatePoints
113 | .. automethod:: SartopoSession._getToken
114 |
115 | .. |shapely_link| raw:: html
116 |
117 | Shapely
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncssar/sartopo_python/1a4b3bb56c015fad36af7652ac9532f128a5c2c3/requirements.txt
--------------------------------------------------------------------------------
/sartopo_python.egg-info/PKG-INFO:
--------------------------------------------------------------------------------
1 | Metadata-Version: 2.1
2 | Name: sartopo-python
3 | Version: 1.1.2
4 | Summary: Python interface to unofficial SARTopo API
5 | Home-page: https://github.com/ncssar/sartopo_python
6 | Author: Tom Grundy
7 | Author-email: nccaves@yahoo.com
8 | License: UNKNOWN
9 | Download-URL: https://github.com/ncssar/sartopo_python/archive/1.1.2.tar.gz
10 | Description: # sartopo_python
11 |
12 | Sartopo / Caltopo currently does not have a publically available API;
13 | this code calls the non-publicized API that could change at any time.
14 |
15 | This module is intended to provide a simple, API-version-agnostic sartopo
16 | interface to other appliactions.
17 |
18 | This python code is in no way supported or maintained by caltopo LLC
19 | or the authors of caltopo.com or sartopo.com.
20 |
21 | ## New for v1.1.0. 5-30-2020:
22 | Signed requests for online maps are now supported. The same requests that work here for offline maps are now also working for online maps. See the signed request explanation at the bottom of this README file.
23 |
24 | ## New for v1.0.6 3-30-2020:
25 | getFeatures now returns the entire json object for each feature. The top level keys should be id, geometry, and properties. This allows preservation of things like marker-symbol, folder, coordinates, and so on when moving an existing marker.
26 |
27 | ## Installation:
28 | ```
29 | pip install sartopo_python
30 | ```
31 |
32 | ## Provided functions in class SartopoSession:
33 | ### \_\_init\_\_ - create a new session
34 | - domainAndPort="localhost:8080"
35 | - mapID[required]=None
36 |
37 | The remaining arguments are only needed to generate signed requests for online maps at sartopo.com; see the signed request explanation at the bottom of this README file.
38 | - configpath
39 | - account
40 | - id
41 | - key
42 | - expires
43 | ### getFeatures - get a list of map features
44 | - featureClass=None - "Marker" etc to return only markers
45 | - since=0 - get features only since this timestamp
46 | ### addFolder - create a SARTopo folder
47 | - label="New Folder"
48 | ### addMarker - create a SARTopo marker
49 | - lat
50 | - lon
51 | - title="New Marker"
52 | - description=""
53 | - color="FF0000"
54 | - symbol="point"
55 | - rotation=None
56 | - folderId=None
57 | - (beginning in 1.0.4) existingId="" - specify this to edit an existing marker
58 | ## EXAMPLES:
59 | ```
60 | # from sartopo_python import SartopoSession
61 | # import time
62 | #
63 | # sts=SartopoSession("localhost:8080","")
64 | # fid=sts.addFolder("MyFolder")
65 | # sts.addMarker(39,-120,"stuff")
66 | # sts.addMarker(39.01,-120.01,"myStuff",folderId=fid)
67 | # r=sts.getFeatures("Marker")
68 | # print("r:"+str(r))
69 | # print("moving the marker after a pause:"+r[0]['id'])
70 | # time.sleep(5)
71 | # sts.addMarker(39.02,-120.02,r[0]['properties']['title'],existingId=r[0]['id'])
72 | #
73 | # sts2=SartopoSession(
74 | # "sartopo.com",
75 | # "",
76 | # configpath="../../sts.ini",
77 | # account="")
78 | # fid2=sts2.addFolder("MyOnlineFolder")
79 | # sts2.addMarker(39,-120,"onlineStuff")
80 | # sts2.addMarker(39.01,-119.99,"onlineStuff2",folderId=fid2)
81 | # r2=sts2.getFeatures("Marker")
82 | # print("return value from getFeatures('Marker'):")
83 | # print(json.dumps(r2,indent=3))
84 | # time.sleep(15)
85 | # print("moving online after a pause:"+r2[0]['id'])
86 | # sts2.addMarker(39.02,-119.98,r2[0]['properties']['title'],existingId=r2[0]['id'])
87 | ```
88 | ## Signed Requests
89 | Requests to localhost do not require any authentication; requests to sartopo.com do require authentication in the form of request signatures.
90 |
91 | If the sartopo session object was created with 'sartopo.com' as part of the URL, then this module will sign all requests before sending.
92 |
93 | Authenticaion information required to generate the signed requests includes an account expiration timestamp, a public key, and an ID code. For a good explanation of how to determine those three items, see the README at https://github.com/elliottshane/sme-sartopo-mapsrv.
94 |
95 | Once those three items are determined, they should be stored in a configparser-compatible file that should look like the following:
96 | ```
97 | # sartopo_pyhton config file
98 | # This file contains credentials used to send API map requests
99 | # to sartopo.com. Protect and do not distribute these credentials.
100 |
101 | [myaccount@gmail.com]
102 | id=123456ABCDEF
103 | key=aBcDeF12345somepublickey
104 | expires=1234567890
105 | ```
106 | An explanation of how the SartopoSession constructor arguments are used to determine credentials, if sartopo.com is in the URL:
107 | ```
108 | # if configpath and account are specified,
109 | # conigpath must be the full pathname of a configparser-compliant
110 | # config file, and account must be the name of a section within it,
111 | # containing keys 'id', 'key', and 'expires'.
112 | # otherwise, those parameters must have been specified in this object's
113 | # constructor.
114 | # if both are specified, first the config section is read and then
115 | # any parameters of this object are used to override the config file
116 | # values.
117 | # if any of those three values are still not specified, abort.
118 | ```
119 |
120 |
121 | Platform: UNKNOWN
122 | Classifier: Programming Language :: Python :: 3
123 | Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
124 | Classifier: Operating System :: OS Independent
125 | Classifier: Development Status :: 4 - Beta
126 | Description-Content-Type: text/markdown
127 |
--------------------------------------------------------------------------------
/sartopo_python.egg-info/SOURCES.txt:
--------------------------------------------------------------------------------
1 | README.md
2 | setup.cfg
3 | setup.py
4 | sartopo_python/__init__.py
5 | sartopo_python/sartopo_python.py
6 | sartopo_python.egg-info/PKG-INFO
7 | sartopo_python.egg-info/SOURCES.txt
8 | sartopo_python.egg-info/dependency_links.txt
9 | sartopo_python.egg-info/requires.txt
10 | sartopo_python.egg-info/top_level.txt
--------------------------------------------------------------------------------
/sartopo_python.egg-info/dependency_links.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sartopo_python.egg-info/requires.txt:
--------------------------------------------------------------------------------
1 | requests
2 |
--------------------------------------------------------------------------------
/sartopo_python.egg-info/top_level.txt:
--------------------------------------------------------------------------------
1 | sartopo_python
2 |
--------------------------------------------------------------------------------
/sartopo_python/__init__.py:
--------------------------------------------------------------------------------
1 | from sartopo_python.sartopo_python import SartopoSession
--------------------------------------------------------------------------------
/sartopo_python/__pycache__/__init__.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncssar/sartopo_python/1a4b3bb56c015fad36af7652ac9532f128a5c2c3/sartopo_python/__pycache__/__init__.cpython-37.pyc
--------------------------------------------------------------------------------
/sartopo_python/__pycache__/sartopo_python.cpython-37.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ncssar/sartopo_python/1a4b3bb56c015fad36af7652ac9532f128a5c2c3/sartopo_python/__pycache__/sartopo_python.cpython-37.pyc
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | description-file = README.md
3 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | ###### setup.py package setup script for pyCalTopo ######
2 |
3 | import setuptools
4 |
5 | with open("README.md", "r") as fh:
6 | long_description = fh.read()
7 |
8 | setuptools.setup(
9 | name="sartopo_python",
10 | version="2.0.0",
11 | author="Tom Grundy",
12 | author_email="nccaves@yahoo.com",
13 | description="Python interface to unofficial CalTopo/SARTopo API",
14 | long_description=long_description,
15 | long_description_content_type="text/markdown",
16 | url="https://github.com/ncssar/sartopo_python",
17 | packages=setuptools.find_packages(),
18 | download_url="https://github.com/ncssar/sartopo_python/archive/2.0.0.tar.gz",
19 | install_requires=[
20 | 'Shapely>=2.0.2',
21 | 'requests'
22 | ],
23 | classifiers=[
24 | "Programming Language :: Python :: 3",
25 | "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
26 | "Operating System :: OS Independent",
27 | "Development Status :: 4 - Beta",
28 | ],
29 | )
30 |
--------------------------------------------------------------------------------