rest_examples.rst 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. .. _importer_rest_examples:
  2. Importer REST API examples
  3. ==========================
  4. Mass configuring a directory of shapefiles
  5. ------------------------------------------
  6. In order to initiate an import of the ``c:\data\tasmania`` directory into the existing ``tasmania`` workspace:
  7. 1. The following JSON will be POSTed to GeoServer.
  8. .. code-block:: json
  9. :caption: import.json
  10. {
  11. "import": {
  12. "targetWorkspace": {
  13. "workspace": {
  14. "name": "tasmania"
  15. }
  16. },
  17. "data": {
  18. "type": "directory",
  19. "location": "C:/data/tasmania"
  20. }
  21. }
  22. }
  23. 2. This curl command can be used for the purpose:
  24. .. code-block:: bash
  25. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  26. -d @import.json \
  27. "http://localhost:8080/geoserver/rest/imports"
  28. The importer will locate the files to be imported, and automatically prepare the tasks, returning the following response:
  29. .. code-block:: json
  30. {
  31. "import": {
  32. "id": 9,
  33. "href": "http://localhost:8080/geoserver/rest/imports/9",
  34. "state": "PENDING",
  35. "archive": false,
  36. "targetWorkspace": {
  37. "workspace": {
  38. "name": "tasmania"
  39. }
  40. },
  41. "data": {
  42. "type": "directory",
  43. "format": "Shapefile",
  44. "location": "C:\\data\\tasmania",
  45. "href": "http://localhost:8080/geoserver/rest/imports/9/data"
  46. },
  47. "tasks": [
  48. {
  49. "id": 0,
  50. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/0",
  51. "state": "READY"
  52. },
  53. {
  54. "id": 1,
  55. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/1",
  56. "state": "READY"
  57. },
  58. {
  59. "id": 2,
  60. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/2",
  61. "state": "READY"
  62. },
  63. {
  64. "id": 3,
  65. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/3",
  66. "state": "READY"
  67. }
  68. ]
  69. }
  70. }
  71. 3. After checking every task is ready, the import can be initiated by executing a POST on the import resource:
  72. .. code-block:: bash
  73. curl -u admin:geoserver -XPOST \
  74. "http://localhost:8080/geoserver/rest/imports/9"
  75. 4. The resource can then be monitored for progress, and eventually final results:
  76. .. code-block:: bash
  77. curl -u admin:geoserver -XGET \
  78. "http://localhost:8080/geoserver/rest/imports/9"
  79. Which in case of successful import will look like:
  80. .. code-block:: json
  81. {
  82. "import": {
  83. "id": 9,
  84. "href": "http://localhost:8080/geoserver/rest/imports/9",
  85. "state": "COMPLETE",
  86. "archive": false,
  87. "targetWorkspace": {
  88. "workspace": {
  89. "name": "tasmania"
  90. }
  91. },
  92. "data": {
  93. "type": "directory",
  94. "format": "Shapefile",
  95. "location": "C:\\data\\tasmania",
  96. "href": "http://localhost:8080/geoserver/rest/imports/9/data"
  97. },
  98. "tasks": [
  99. {
  100. "id": 0,
  101. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/0",
  102. "state": "COMPLETE"
  103. },
  104. {
  105. "id": 1,
  106. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/1",
  107. "state": "COMPLETE"
  108. },
  109. {
  110. "id": 2,
  111. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/2",
  112. "state": "COMPLETE"
  113. },
  114. {
  115. "id": 3,
  116. "href": "http://localhost:8080/geoserver/rest/imports/9/tasks/3",
  117. "state": "COMPLETE"
  118. }
  119. ]
  120. }
  121. }
  122. Configuring a shapefile with no projection information
  123. ------------------------------------------------------
  124. In this case, let's assume we have a single shapefile, :file:`tasmania_cities.shp``, that does not have the :file:`.prj` sidecar file
  125. (the example is equally good for any case where the :file:`prj` file contents cannot be matched to an official EPSG code).
  126. 1. We are going to post the following import definition:
  127. .. code-block:: json
  128. :caption: import.json
  129. {
  130. "import": {
  131. "targetWorkspace": {
  132. "workspace": {
  133. "name": "tasmania"
  134. }
  135. },
  136. "data": {
  137. "type": "file",
  138. "file": "C:/data/tasmania/tasmania_cities.shp"
  139. }
  140. }
  141. }
  142. 2. With the cURL POST command:
  143. .. code-block:: bash
  144. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  145. -d @import.json \
  146. "http://localhost:8080/geoserver/rest/imports"
  147. The response in case the CRS is missing will be:
  148. .. code-block:: json
  149. {
  150. "import": {
  151. "id": 13,
  152. "href": "http://localhost:8080/geoserver/rest/imports/13",
  153. "state": "PENDING",
  154. "archive": false,
  155. "targetWorkspace": {
  156. "workspace": {
  157. "name": "tasmania"
  158. }
  159. },
  160. "data": {
  161. "type": "file",
  162. "format": "Shapefile",
  163. "file": "tasmania_cities.shp"
  164. },
  165. "tasks": [
  166. {
  167. "id": 0,
  168. "href": "http://localhost:8080/geoserver/rest/imports/13/tasks/0",
  169. "state": "NO_CRS"
  170. }
  171. ]
  172. }
  173. }
  174. 3. Drilling into the task layer:
  175. .. code-block:: bash
  176. curl -u admin:geoserver -XGET -H "Content-type: application/json" \
  177. http://localhost:8080/geoserver/rest/imports/13/tasks/0/layer
  178. We can see the srs information is missing:
  179. .. code-block:: json
  180. {
  181. "layer": {
  182. "name": "tasmania_cities",
  183. "href": "http://localhost:8080/geoserver/rest/imports/13/tasks/0/layer",
  184. "title": "tasmania_cities",
  185. "originalName": "tasmania_cities",
  186. "nativeName": "tasmania_cities",
  187. "bbox": {
  188. "minx": 146.2910004483,
  189. "miny": -43.85100181689,
  190. "maxx": 148.2910004483,
  191. "maxy": -41.85100181689
  192. },
  193. "attributes": [
  194. {
  195. "name": "the_geom",
  196. "binding": "org.locationtech.jts.geom.MultiPoint"
  197. },
  198. {
  199. "name": "CITY_NAME",
  200. "binding": "java.lang.String"
  201. },
  202. {
  203. "name": "ADMIN_NAME",
  204. "binding": "java.lang.String"
  205. },
  206. {
  207. "name": "CNTRY_NAME",
  208. "binding": "java.lang.String"
  209. },
  210. {
  211. "name": "STATUS",
  212. "binding": "java.lang.String"
  213. },
  214. {
  215. "name": "POP_CLASS",
  216. "binding": "java.lang.String"
  217. }
  218. ],
  219. "style": {
  220. "name": "tasmania_tasmania_cities2",
  221. "href": "http://localhost:8080/geoserver/rest/imports/13/tasks/0/layer/style"
  222. }
  223. }
  224. }
  225. 4. Use the following json snippet to update the SRS:
  226. .. code-block:: bash
  227. :caption: layerUpdate.json
  228. {
  229. layer : {
  230. srs: "EPSG:4326"
  231. }
  232. }
  233. Using cURL PUT command:
  234. .. code-block:: bash
  235. curl -u admin:geoserver -XPUT -H "Content-type: application/json" \
  236. -d @layerUpdate.json \
  237. "http://localhost:8080/geoserver/rest/imports/13/tasks/0/layer/"
  238. 5. Getting the import definition again:
  239. .. code-block:: bash
  240. curl -u admin:geoserver -XGET -H "Content-type: application/json" \
  241. http://localhost:8080/geoserver/rest/imports/13/tasks/0
  242. The import is now ready to execute:
  243. .. code-block:: json
  244. {
  245. "import": {
  246. "id": 13,
  247. "href": "http://localhost:8080/geoserver/rest/imports/13",
  248. "state": "PENDING",
  249. "archive": false,
  250. "targetWorkspace": {
  251. "workspace": {
  252. "name": "tasmania"
  253. }
  254. },
  255. "data": {
  256. "type": "file",
  257. "format": "Shapefile",
  258. "file": "tasmania_cities.shp"
  259. },
  260. "tasks": [
  261. {
  262. "id": 0,
  263. "href": "http://localhost:8080/geoserver/rest/imports/13/tasks/0",
  264. "state": "READY"
  265. }
  266. ]
  267. }
  268. }
  269. 6. A POST request will execute the import:
  270. .. code-block:: bash
  271. curl -u admin:geoserver -XPOST \
  272. "http://localhost:8080/geoserver/rest/imports/13"
  273. With a successful import marking the task as ``COMPLETE``:
  274. .. code-block:: json
  275. {
  276. "import": {
  277. "id": 13,
  278. "href": "http://localhost:8080/geoserver/rest/imports/13",
  279. "state": "COMPLETE",
  280. "archive": false,
  281. "targetWorkspace": {
  282. "workspace": {
  283. "name": "tasmania"
  284. }
  285. },
  286. "data": {
  287. "type": "file",
  288. "format": "Shapefile",
  289. "file": "tasmania_cities.shp"
  290. },
  291. "tasks": [
  292. {
  293. "id": 0,
  294. "href": "http://localhost:8080/geoserver/rest/imports/13/tasks/0",
  295. "state": "COMPLETE"
  296. }
  297. ]
  298. }
  299. }
  300. Uploading a Shapefile to PostGIS
  301. --------------------------------
  302. This example shows the process for uploading a Shapefile (in a zip file) to an existing PostGIS datastore (cite:postgis).
  303. 1. Setup ``cite:postgis`` datastore:
  304. .. literalinclude:: files/postgis.json
  305. :language: json
  306. :caption: postgis.json
  307. Using curl POST:
  308. .. code-block:: bash
  309. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  310. -d @postgis.json \
  311. "http://localhost:8080/geoserver/rest/workspaces/cite/datastores.json"
  312. 2. Create the import definition:
  313. .. literalinclude:: files/import.json
  314. :language: json
  315. :caption: import.json
  316. POST this definition to /geoserver/rest/imports:
  317. .. code-block:: bash
  318. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  319. -d @import.json \
  320. "http://localhost:8080/geoserver/rest/imports"
  321. The response will contain the import ID.
  322. 3. We now have an empty import with no tasks. To add a task, POST the shapefile to the list of tasks:
  323. .. code-block:: bash
  324. curl -u admin:geoserver \
  325. -F name=myshapefile.zip -F filedata=@myshapefile.zip \
  326. "http://localhost:8080/geoserver/rest/imports/14/tasks"
  327. 4. Since we sent a shapefile, importer assumes the target will be a shapefile store. To import to PostGIS, we will need to reset it.
  328. Create the following JSON file:
  329. .. code-block:: json
  330. :caption: target.json
  331. {
  332. "dataStore": {
  333. "name":"postgis"
  334. }
  335. }
  336. PUT this file to /geoserver/rest/imports/14/tasks/0/target:
  337. .. code-block:: bash
  338. curl -u admin:geoserver -XPUT -H "Content-type: application/json" \
  339. -d @target.json \
  340. "http://localhost:8080/geoserver/rest/imports/14/tasks/0/target"
  341. 5. Finally, we execute the import by sending a POST to /geoserver/rest/imports/14:
  342. .. code-block:: bash
  343. curl -u admin:geoserver -XPOST \
  344. "http://localhost:8080/geoserver/rest/imports/14"
  345. Uploading a CSV file to PostGIS while transforming it
  346. -----------------------------------------------------
  347. A remote sensing tool is generating CSV files with some locations and measurements, that we want to upload
  348. into PostGIS as a new spatial table.
  349. 1. First, we are going to create a empty import with an existing postgis store as the target:
  350. .. code-block:: bash
  351. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  352. -d @import.json \
  353. "http://localhost:8080/geoserver/rest/imports"
  354. Where :file:`import.json` is:
  355. .. literalinclude:: files/import.json
  356. :language: json
  357. :caption: import.json
  358. 2. Then, we are going to POST the csv file to the tasks list.
  359. .. literalinclude:: files/values.csv
  360. :language: text
  361. :caption: values.csv
  362. In order to create an import task for it:
  363. .. code-block:: bash
  364. curl -u admin:geoserver -F name=test -F filedata=@values.csv \
  365. "http://localhost:8080/geoserver/rest/imports/0/tasks"
  366. And we are going to get back a new task definition, with a notification that the CRS is missing:
  367. .. code-block:: json
  368. {
  369. "task": {
  370. "id": 0,
  371. "href": "http://localhost:8080/geoserver/rest/imports/0/tasks/0",
  372. "state": "NO_CRS",
  373. "updateMode": "CREATE",
  374. "data": {
  375. "type": "file",
  376. "format": "CSV",
  377. "file": "values.csv"
  378. },
  379. "target": {
  380. "href": "http://localhost:8080/geoserver/rest/imports/0/tasks/0/target",
  381. "dataStore": {
  382. "name": "postgis",
  383. "type": "PostGIS"
  384. }
  385. },
  386. "progress": "http://localhost:8080/geoserver/rest/imports/0/tasks/0/progress",
  387. "layer": {
  388. "name": "values",
  389. "href": "http://localhost:8080/geoserver/rest/imports/0/tasks/0/layer"
  390. },
  391. "transformChain": {
  392. "type": "vector",
  393. "transforms": []
  394. }
  395. }
  396. }
  397. 3. Force the CRS by updating the layer:
  398. .. literalinclude:: files/layerUpdate.json
  399. :language: json
  400. :caption: layerUpdate.json
  401. Using PUT to update task layer:
  402. .. code-block:: bash
  403. curl -u admin:geoserver -XPUT -H "Content-type: application/json" \
  404. -d @layerUpdate.json \
  405. "http://localhost:8080/geoserver/rest/imports/0/tasks/0/layer/"
  406. Updating the srs:
  407. .. code-block:: json
  408. {
  409. "layer": {
  410. "name": "values",
  411. "href": "http://localhost:8080/geoserver/rest/imports/0/tasks/0/layer",
  412. "title": "values",
  413. "originalName": "values",
  414. "nativeName": "values",
  415. "srs": "EPSG:4326",
  416. "bbox": {
  417. "minx": 0,
  418. "miny": 0,
  419. "maxx": -1,
  420. "maxy": -1
  421. },
  422. "attributes": [
  423. {
  424. "name": "AssetID",
  425. "binding": "java.lang.Integer"
  426. },
  427. {
  428. "name": "SampleTime",
  429. "binding": "java.lang.String"
  430. },
  431. {
  432. "name": "Lat",
  433. "binding": "java.lang.Double"
  434. },
  435. {
  436. "name": "Lon",
  437. "binding": "java.lang.Double"
  438. },
  439. {
  440. "name": "Value",
  441. "binding": "java.lang.Double"
  442. }
  443. ],
  444. "style": {
  445. "name": "point",
  446. "href": "http://localhost:8080/geoserver/rest/imports/0/tasks/0/layer/style"
  447. }
  448. }
  449. }
  450. 4. Then, we are going to create a transformation mapping the Lat/Lon columns to a point:
  451. .. literalinclude:: files/toPoint.json
  452. :language: json
  453. :caption: toPoint.json
  454. The above will be uploaded task transforms:
  455. .. code-block:: bash
  456. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  457. -d @toPoint.json \
  458. "http://localhost:8080/geoserver/rest/imports/0/tasks/0/transforms"
  459. 5. Now the import is ready to run, and we'll execute it using:
  460. .. code-block:: bash
  461. curl -u admin:geoserver -XPOST \
  462. "http://localhost:8080/geoserver/rest/imports/0"
  463. 6. The new layer is created in PostGIS and registered in GeoServer as a new layer.
  464. In case the features in the CSV need to be appended to an existing layer a PUT request against the task might be performed, changing its
  465. updateMode from "CREATE" to "APPEND". Changing it to "REPLACE" instead will preserve the layer, but remove the old contents and replace
  466. them with the newly uploaded ones.
  467. Replacing PostGIS table using the contents of a CSV file
  468. --------------------------------------------------------
  469. To update the ``values`` layer with new content:
  470. #. Create a new import into ``cite:postgis``:
  471. .. code-block:: bash
  472. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  473. -d @import.json "http://localhost:8080/geoserver/rest/imports"
  474. Using:
  475. .. literalinclude:: files/import.json
  476. :language: json
  477. :caption: import.json
  478. #. Use :file:`replace.csv` to create a new task:
  479. .. code-block:: bash
  480. curl -u admin:geoserver -XPOST \
  481. -F filedata=@replace.csv \
  482. "http://localhost:8080/geoserver/rest/imports/1/tasks"
  483. The csv file has an additional column:
  484. .. literalinclude:: files/replace.csv
  485. :language: text
  486. :caption: replace.csv
  487. #. Update task with as a "REPLACE" and supply srs information:
  488. .. code-block:: bash
  489. curl -u admin:geoserver -XPUT -H "Content-type: application/json" \
  490. -d @taskUpdate.json \
  491. "http://localhost:8080/geoserver/rest/imports/1/tasks/0"
  492. Using:
  493. .. literalinclude:: files/taskUpdate.json
  494. :language: json
  495. :caption: taskUpdate.json
  496. #. Update transform to supply a geometry column:
  497. .. code-block:: bash
  498. curl -u admin:geoserver -XPOST -H "Content-type: application/json" \
  499. -d @toPoint.json \
  500. "http://localhost:8080/geoserver/rest/imports/1/tasks/0/transforms"
  501. Using:
  502. .. literalinclude:: files/toPoint.json
  503. :language: json
  504. :caption: toPoint.json
  505. #. Double check import:
  506. .. code-block:: bash
  507. curl -u admin:geoserver -XGET \
  508. http://localhost:8080/geoserver/rest/imports/1.json
  509. .. code-block:: json
  510. :emphasize-lines: 15
  511. {
  512. "import": {
  513. "id": 2,
  514. "href": "http://localhost:8080/geoserver/rest/imports/1",
  515. "state": "PENDING",
  516. "archive": false,
  517. "targetWorkspace": {
  518. "workspace": {
  519. "name": "cite",
  520. "isolated": false
  521. }
  522. },
  523. "targetStore": {
  524. "dataStore": {
  525. "name": "postgis",
  526. "type": "PostGIS"
  527. }
  528. },
  529. "tasks": [
  530. {
  531. "id": 0,
  532. "href": "http://localhost:8080/geoserver/rest/imports/1/tasks/0",
  533. "state": "READY"
  534. }
  535. ]
  536. }
  537. }
  538. Task:
  539. .. code-block:: bash
  540. curl -u admin:geoserver -XGET \
  541. http://localhost:8080/geoserver/rest/imports/1/tasks/0.json
  542. .. code-block:: json
  543. :emphasize-lines: 5
  544. {
  545. "task": {
  546. "id": 0,
  547. "href": "http://localhost:8080/geoserver/rest/imports/2/tasks/0",
  548. "state": "READY",
  549. "updateMode": "REPLACE",
  550. "data": {
  551. "type": "file",
  552. "format": "CSV",
  553. "file": "replace.csv"
  554. },
  555. "target": {
  556. "href": "http://localhost:8080/geoserver/rest/imports/2/tasks/0/target",
  557. "dataStore": {
  558. "name": "postgis",
  559. "type": "PostGIS"
  560. }
  561. },
  562. "progress": "http://localhost:8080/geoserver/rest/imports/2/tasks/0/progress",
  563. "layer": {
  564. "name": "replace",
  565. "href": "http://localhost:8080/geoserver/rest/imports/2/tasks/0/layer"
  566. },
  567. "transformChain": {
  568. "type": "vector",
  569. "transforms": [
  570. {
  571. "type": "AttributesToPointGeometryTransform",
  572. "href": "http://localhost:8080/geoserver/rest/imports/2/tasks/0/transforms/0"
  573. }
  574. ]
  575. }
  576. }
  577. }
  578. Check layer to ensure ``name`` indicates layer to replace, and ``nativeName`` indicates
  579. the table contents to replace:
  580. .. code-block:: bash
  581. curl -u admin:geoserver -XGET \
  582. http://localhost:8080/geoserver/rest/imports/1/tasks/0/layer.json
  583. .. code-block:: json
  584. :emphasize-lines: 3,5,6,7
  585. {
  586. "layer": {
  587. "name": "values",
  588. "href": "http://localhost:8080/geoserver/rest/imports/1/tasks/0/layer",
  589. "title": "values",
  590. "originalName": "replace",
  591. "nativeName": "replace",
  592. "srs": "EPSG:4326",
  593. "bbox": {
  594. "minx": 0,
  595. "miny": 0,
  596. "maxx": -1,
  597. "maxy": -1
  598. },
  599. "attributes": [
  600. {
  601. "name": "AssetID",
  602. "binding": "java.lang.Integer"
  603. },
  604. {
  605. "name": "SampleTime",
  606. "binding": "java.lang.String"
  607. },
  608. {
  609. "name": "Lat",
  610. "binding": "java.lang.Double"
  611. },
  612. {
  613. "name": "Lon",
  614. "binding": "java.lang.Double"
  615. },
  616. {
  617. "name": "Value",
  618. "binding": "java.lang.Integer"
  619. }
  620. ],
  621. "style": {
  622. "name": "point",
  623. "href": "http://localhost:8080/geoserver/rest/imports/1/tasks/0/layer/style"
  624. }
  625. }
  626. }
  627. Transform:
  628. .. code-block:: bash
  629. curl -u admin:geoserver -XGET \
  630. http://localhost:8080/geoserver/rest/imports/1/tasks/0/transforms/0.json
  631. #. To run the import:
  632. .. code-block:: bash
  633. curl -u admin:geoserver -XPOST \
  634. "http://localhost:8080/geoserver/rest/imports/1"
  635. Uploading and optimizing a GeoTiff with ground control points
  636. -------------------------------------------------------------
  637. A data supplier is periodically providing GeoTiffs that we need to configure in GeoServer.
  638. The GeoTIFF is referenced via Ground Control Points, is organized by stripes, and has no overviews.
  639. The objective is to rectify, optimize and publish it via the importer.
  640. First, we are going to create a empty import with no store as the target::
  641. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @import.json "http://localhost:8080/geoserver/rest/imports"
  642. Where import.json is::
  643. {
  644. "import": {
  645. "targetWorkspace": {
  646. "workspace": {
  647. "name": "sf"
  648. }
  649. }
  650. }
  651. }
  652. Then, we are going to POST the GeoTiff file to the tasks list, in order to create an import task for it::
  653. curl -u admin:geoserver -F name=test -F filedata=@box_gcp_fixed.tif "http://localhost:8080/geoserver/rest/imports/0/tasks"
  654. We are then going to append the transformations to rectify (gdalwarp), retile (gdal_translate) and add overviews (gdaladdo) to it::
  655. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @warp.json "http://localhost:8080/geoserver/rest/imports/0/tasks/0/transforms"
  656. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @gtx.json "http://localhost:8080/geoserver/rest/imports/0/tasks/0/transforms"
  657. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @gad.json "http://localhost:8080/geoserver/rest/imports/0/tasks/0/transforms"
  658. ``warp.json`` is::
  659. {
  660. "type": "GdalWarpTransform",
  661. "options": [ "-t_srs", "EPSG:4326"]
  662. }
  663. ``gtx.json`` is::
  664. {
  665. "type": "GdalTranslateTransform",
  666. "options": [ "-co", "TILED=YES", "-co", "BLOCKXSIZE=512", "-co", "BLOCKYSIZE=512"]
  667. }
  668. ``gad.json`` is::
  669. {
  670. "type": "GdalAddoTransform",
  671. "options": [ "-r", "average"],
  672. "levels" : [2, 4, 8, 16]
  673. }
  674. Now the import is ready to run, and we'll execute it using::
  675. curl -u admin:geoserver -XPOST "http://localhost:8080/geoserver/rest/imports/0"
  676. A new layer ``box_gcp_fixed`` layer will appear in GeoServer, with an underlying GeoTiff file ready
  677. for web serving.
  678. Adding a new granule into an existing mosaic
  679. --------------------------------------------
  680. A data supplier is periodically providing new time based imagery that we need to add into an existing mosaic
  681. in GeoServer.
  682. The imagery is in GeoTiff format, and lacks a good internal structure, which needs to be aligned with
  683. the one into the other images.
  684. First, we are going to create a import with an indication of where the granule is located, and
  685. the target store:
  686. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @import.json "http://localhost:8080/geoserver/rest/imports"
  687. Where import.json is::
  688. {
  689. "import": {
  690. "targetWorkspace": {
  691. "workspace": {
  692. "name": "topp"
  693. }
  694. },
  695. "data": {
  696. "type": "file",
  697. "file": "/home/aaime/devel/gisData/ndimensional/data/world/world.200407.3x5400x2700.tiff"
  698. },
  699. "targetStore": {
  700. "dataStore": {
  701. "name": "bluemarble"
  702. }
  703. }
  704. }
  705. }
  706. We are then going to append the transformations to harmonize the file with the rest of the mosaic::
  707. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @gtx.json "http://localhost:8080/geoserver/rest/imports/0/tasks/0/transforms"
  708. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @gad.json "http://localhost:8080/geoserver/rest/imports/0/tasks/0/transforms"
  709. ``gtx.json`` is::
  710. {
  711. "type": "GdalTranslateTransform",
  712. "options": [ "-co", "TILED=YES"]
  713. }
  714. ``gad.json`` is::
  715. {
  716. "type": "GdalAddoTransform",
  717. "options": [ "-r", "average"],
  718. "levels" : [2, 4, 8, 16, 32, 64, 128]
  719. }
  720. Now the import is ready to run, and we'll execute it using::
  721. curl -u admin:geoserver -XPOST "http://localhost:8080/geoserver/rest/imports/0"
  722. The new granule will be ingested into the mosaic, and will thus be available for time based requests.
  723. Asynchronously fetching and importing data from a remote server
  724. ---------------------------------------------------------------
  725. We assume a remote FTP server contains multiple shapefiles that we need to import in GeoServer
  726. as new layers. The files are large, and the server has much better bandwidth than the client,
  727. so it's best if GeoServer performs the data fetching on its own.
  728. In this case a asynchronous request using ``remote`` data will be the best fit::
  729. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @import.json "http://localhost:8080/geoserver/rest/imports?async=true"
  730. Where import.json is::
  731. {
  732. "import": {
  733. "targetWorkspace": {
  734. "workspace": {
  735. "name": "topp"
  736. }
  737. },
  738. "data": {
  739. "type": "remote",
  740. "location": "ftp://myserver/data/bc_shapefiles",
  741. "username": "dan",
  742. "password": "secret"
  743. }
  744. }
  745. }
  746. The request will return immediately with an import context in "INIT" state, and it will remain in such
  747. state until the data is fetched and the tasks created.
  748. Once the state switches to "PENDING" the import will be ready for execution. Since there is
  749. a lot of shapefiles to process, also the import run will be done in asynchronous mode::
  750. curl -u admin:geoserver -XPOST "http://localhost:8080/geoserver/rest/imports/0?async=true"
  751. The response will return immediately in this case as well, and the progress can be followed as the
  752. tasks in the import switch state.
  753. Importing and optimizing a large image with a single request
  754. ------------------------------------------------------------
  755. A large image appears every now and then on a mounted disk share, the image needs to be
  756. optimized and imported into GeoServer as a new layer.
  757. Since the source is large and we need to copy it on the local disk where the data dir resides,
  758. a "remote" data is the right tool for the job, an asynchronous execution is also recommended
  759. to avoid waiting on a possibly large command.
  760. In this case the request will also contains the "exec=true" parameter to force the importer
  761. an immediate execution of the command.
  762. The request will then look as follows::
  763. curl -u admin:geoserver -XPOST -H "Content-type: application/json" -d @import.json "http://localhost:8080/geoserver/rest/imports?async=true&exec=true"
  764. Where import.json is::
  765. {
  766. "import": {
  767. "targetWorkspace": {
  768. "workspace": {
  769. "name": "topp"
  770. }
  771. },
  772. "data": {
  773. "type": "remote",
  774. "location": "\/mnt\/remoteDisk\/bluemarble.tiff"
  775. },
  776. "transforms": [
  777. {
  778. "type": "GdalTranslateTransform",
  779. "options": [
  780. "-co", "TILED=YES",
  781. "-co", "COMPRESS=JPEG",
  782. "-co", "JPEG_QUALITY=85",
  783. "-co", "PHOTOMETRIC=YCBCR"
  784. ]
  785. },
  786. {
  787. "type": "GdalAddoTransform",
  788. "options": [
  789. "-r",
  790. "average",
  791. "--config", "COMPRESS_OVERVIEW", "JPEG",
  792. "--config", "PHOTOMETRIC_OVERVIEW", "YCBCR"
  793. ],
  794. "levels": [ 2, 4, 8, 16, 32, 64 ]
  795. }
  796. ]
  797. }
  798. }
  799. Given the request is asynchronous, the client will have to poll the server in order to check
  800. if the initialization and execution have succeeded.