geo_works 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (336) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +34 -0
  3. data/.csslintrc +2 -0
  4. data/.engine_cart.yml +1 -0
  5. data/.eslintignore +1 -0
  6. data/.eslintrc +8 -0
  7. data/.fcrepo_wrapper +3 -0
  8. data/.gitignore +14 -0
  9. data/.rubocop.yml +105 -0
  10. data/.solr_wrapper +7 -0
  11. data/.travis.yml +33 -0
  12. data/CONTRIBUTING.md +159 -0
  13. data/Gemfile +48 -0
  14. data/LICENSE +202 -0
  15. data/README.md +143 -0
  16. data/Rakefile +25 -0
  17. data/app/assets/images/geo_works/.keep +0 -0
  18. data/app/assets/images/geo_works/images/geocoder.png +0 -0
  19. data/app/assets/images/geo_works/images/move-handle.png +0 -0
  20. data/app/assets/images/geo_works/images/resize-handle.png +0 -0
  21. data/app/assets/images/geo_works/images/throbber.gif +0 -0
  22. data/app/assets/javascripts/geo_works/Control.Geocoder.js +1056 -0
  23. data/app/assets/javascripts/geo_works/application.js +4 -0
  24. data/app/assets/javascripts/geo_works/bounding_box_selector.js +107 -0
  25. data/app/assets/javascripts/geo_works/es6-modules.js +7 -0
  26. data/app/assets/javascripts/geo_works/geo_works_boot.es6 +8 -0
  27. data/app/assets/javascripts/geo_works/leaflet-boundingbox.js +467 -0
  28. data/app/assets/javascripts/geo_works/relationships.js +3 -0
  29. data/app/assets/javascripts/geo_works/relationships/child_works.es6 +20 -0
  30. data/app/assets/javascripts/geo_works/relationships/parent_works.es6 +20 -0
  31. data/app/assets/javascripts/geo_works/relationships/related_works.es6 +187 -0
  32. data/app/assets/stylesheets/geo_works/Control.Geocoder.scss +104 -0
  33. data/app/assets/stylesheets/geo_works/application.css +18 -0
  34. data/app/assets/stylesheets/geo_works/bounding_box.scss +15 -0
  35. data/app/assets/stylesheets/geo_works/leaflet-boundingbox.scss +17 -0
  36. data/app/assets/stylesheets/geo_works/related_works.scss +29 -0
  37. data/app/assets/stylesheets/geo_works/thumbnails.scss +13 -0
  38. data/app/controllers/concerns/geo_works/events_behavior.rb +29 -0
  39. data/app/controllers/concerns/geo_works/file_sets_controller_behavior.rb +31 -0
  40. data/app/controllers/concerns/geo_works/geoblacklight_controller_behavior.rb +29 -0
  41. data/app/controllers/concerns/geo_works/image_works_controller_behavior.rb +9 -0
  42. data/app/controllers/concerns/geo_works/raster_works_controller_behavior.rb +9 -0
  43. data/app/controllers/concerns/geo_works/vector_works_controller_behavior.rb +9 -0
  44. data/app/forms/geo_works/basic_geo_metadata_form.rb +9 -0
  45. data/app/forms/geo_works/external_metadata_file_form.rb +8 -0
  46. data/app/forms/geo_works/georeferenced_form.rb +9 -0
  47. data/app/forms/hyrax/image_work_form.rb +7 -0
  48. data/app/forms/hyrax/raster_work_form.rb +8 -0
  49. data/app/forms/hyrax/vector_work_form.rb +8 -0
  50. data/app/helpers/geo_works/application_helper.rb +4 -0
  51. data/app/helpers/geo_works/bounding_box_helper.rb +73 -0
  52. data/app/helpers/geo_works/file_set_actions_helper.rb +31 -0
  53. data/app/helpers/geo_works/geo_works_helper.rb +22 -0
  54. data/app/helpers/geo_works/populate_metadata_helper.rb +7 -0
  55. data/app/jobs/geoblacklight_job.rb +10 -0
  56. data/app/jobs/geoserver_delivery_job.rb +36 -0
  57. data/app/models/concerns/geo_works/ability.rb +12 -0
  58. data/app/models/concerns/geo_works/basic_geo_metadata.rb +21 -0
  59. data/app/models/concerns/geo_works/external_metadata_file_behavior.rb +31 -0
  60. data/app/models/concerns/geo_works/extractors/fgdc_helper.rb +9 -0
  61. data/app/models/concerns/geo_works/extractors/fgdc_metadata_extractor.rb +114 -0
  62. data/app/models/concerns/geo_works/extractors/iso19139_helper.rb +50 -0
  63. data/app/models/concerns/geo_works/extractors/mods_helper.rb +15 -0
  64. data/app/models/concerns/geo_works/file_set_metadata.rb +15 -0
  65. data/app/models/concerns/geo_works/file_set_presenter_behavior.rb +7 -0
  66. data/app/models/concerns/geo_works/geo_file_format_behavior.rb +37 -0
  67. data/app/models/concerns/geo_works/geo_file_set_behavior.rb +11 -0
  68. data/app/models/concerns/geo_works/georeferenced_behavior.rb +18 -0
  69. data/app/models/concerns/geo_works/image_file_behavior.rb +14 -0
  70. data/app/models/concerns/geo_works/image_work_behavior.rb +69 -0
  71. data/app/models/concerns/geo_works/metadata_extraction_helper.rb +27 -0
  72. data/app/models/concerns/geo_works/raster_file_behavior.rb +14 -0
  73. data/app/models/concerns/geo_works/raster_work_behavior.rb +82 -0
  74. data/app/models/concerns/geo_works/solr_document_behavior.rb +46 -0
  75. data/app/models/concerns/geo_works/vector_file_behavior.rb +14 -0
  76. data/app/models/concerns/geo_works/vector_work_behavior.rb +78 -0
  77. data/app/presenters/geo_works/geo_works_show_presenter.rb +48 -0
  78. data/app/presenters/geo_works/image_work_show_presenter.rb +5 -0
  79. data/app/presenters/geo_works/raster_work_show_presenter.rb +5 -0
  80. data/app/presenters/geo_works/vector_work_show_presenter.rb +5 -0
  81. data/app/processors/geo_works/geoblacklight_event_processor.rb +29 -0
  82. data/app/processors/geo_works/geoblacklight_event_processor/delete_processor.rb +13 -0
  83. data/app/processors/geo_works/geoblacklight_event_processor/processor.rb +28 -0
  84. data/app/processors/geo_works/geoblacklight_event_processor/unknown_event.rb +15 -0
  85. data/app/processors/geo_works/geoblacklight_event_processor/update_processor.rb +15 -0
  86. data/app/processors/geo_works/processors/base_geo_processor.rb +81 -0
  87. data/app/processors/geo_works/processors/gdal.rb +49 -0
  88. data/app/processors/geo_works/processors/image.rb +66 -0
  89. data/app/processors/geo_works/processors/ogr.rb +19 -0
  90. data/app/processors/geo_works/processors/raster.rb +26 -0
  91. data/app/processors/geo_works/processors/raster/aig.rb +40 -0
  92. data/app/processors/geo_works/processors/raster/base.rb +41 -0
  93. data/app/processors/geo_works/processors/raster/dem.rb +29 -0
  94. data/app/processors/geo_works/processors/raster/info.rb +52 -0
  95. data/app/processors/geo_works/processors/rendering.rb +79 -0
  96. data/app/processors/geo_works/processors/vector.rb +24 -0
  97. data/app/processors/geo_works/processors/vector/base.rb +44 -0
  98. data/app/processors/geo_works/processors/vector/info.rb +84 -0
  99. data/app/processors/geo_works/processors/vector/shapefile.rb +20 -0
  100. data/app/processors/geo_works/processors/zip.rb +29 -0
  101. data/app/renderers/geo_works/coverage_renderer.rb +39 -0
  102. data/app/runners/geo_works/runners/raster_derivatives.rb +9 -0
  103. data/app/runners/geo_works/runners/vector_derivatives.rb +9 -0
  104. data/app/schemas/geo_works/basic_geo_metadata_optional.rb +40 -0
  105. data/app/schemas/geo_works/basic_geo_metadata_required.rb +25 -0
  106. data/app/schemas/geo_works/file_set_metadata_required.rb +5 -0
  107. data/app/services/geo_works/authority_service.rb +29 -0
  108. data/app/services/geo_works/delivery/geoserver.rb +118 -0
  109. data/app/services/geo_works/delivery_service.rb +11 -0
  110. data/app/services/geo_works/discovery.rb +4 -0
  111. data/app/services/geo_works/discovery/abstract_document.rb +37 -0
  112. data/app/services/geo_works/discovery/document_builder.rb +46 -0
  113. data/app/services/geo_works/discovery/document_builder/basic_metadata_builder.rb +71 -0
  114. data/app/services/geo_works/discovery/document_builder/composite_builder.rb +21 -0
  115. data/app/services/geo_works/discovery/document_builder/date_builder.rb +53 -0
  116. data/app/services/geo_works/discovery/document_builder/document_helper.rb +10 -0
  117. data/app/services/geo_works/discovery/document_builder/document_path.rb +91 -0
  118. data/app/services/geo_works/discovery/document_builder/layer_info_builder.rb +65 -0
  119. data/app/services/geo_works/discovery/document_builder/references_builder.rb +101 -0
  120. data/app/services/geo_works/discovery/document_builder/slug_builder.rb +24 -0
  121. data/app/services/geo_works/discovery/document_builder/spatial_builder.rb +37 -0
  122. data/app/services/geo_works/discovery/document_builder/wxs.rb +76 -0
  123. data/app/services/geo_works/discovery/geoblacklight_document.rb +152 -0
  124. data/app/services/geo_works/events_generator.rb +24 -0
  125. data/app/services/geo_works/events_generator/composite_generator.rb +18 -0
  126. data/app/services/geo_works/events_generator/geoblacklight_event_generator.rb +53 -0
  127. data/app/services/geo_works/events_generator/geoserver_event_generator.rb +33 -0
  128. data/app/services/geo_works/file_set_derivatives_service.rb +67 -0
  129. data/app/services/geo_works/image_format_service.rb +6 -0
  130. data/app/services/geo_works/metadata_format_service.rb +6 -0
  131. data/app/services/geo_works/raster_format_service.rb +6 -0
  132. data/app/services/geo_works/vector_format_service.rb +6 -0
  133. data/app/services/hyrax/curation_concern.rb +18 -0
  134. data/app/values/geo_works/coverage.rb +36 -0
  135. data/app/values/geo_works/time_period.rb +30 -0
  136. data/app/views/geo_works/_attribute_rows.html.erb +4 -0
  137. data/app/views/geo_works/_form_progress.html.erb +50 -0
  138. data/app/views/geo_works/_guts4form.html.erb +47 -0
  139. data/app/views/geo_works/_member.html.erb +11 -0
  140. data/app/views/geo_works/_metadata.html.erb +13 -0
  141. data/app/views/geo_works/_relationships.html.erb +12 -0
  142. data/app/views/geo_works/_representative_media.html.erb +5 -0
  143. data/app/views/geo_works/file_sets/_form.html.erb +48 -0
  144. data/app/views/geo_works/file_sets/actions/_default_actions.html.erb +16 -0
  145. data/app/views/geo_works/file_sets/actions/_image_actions.html.erb +22 -0
  146. data/app/views/geo_works/file_sets/actions/_metadata_actions.html.erb +16 -0
  147. data/app/views/geo_works/file_sets/actions/_raster_actions.html.erb +25 -0
  148. data/app/views/geo_works/file_sets/actions/_vector_actions.html.erb +25 -0
  149. data/app/views/geo_works/file_sets/media_display/_geo.html.erb +16 -0
  150. data/app/views/geo_works/file_sets/new.html.erb +12 -0
  151. data/app/views/geo_works/related/_child_member.html.erb +13 -0
  152. data/app/views/geo_works/related/_child_works.html.erb +24 -0
  153. data/app/views/geo_works/related/_external_metadata_file_member.html.erb +11 -0
  154. data/app/views/geo_works/related/_external_metadata_files.html.erb +24 -0
  155. data/app/views/geo_works/related/_geo_files.html.erb +24 -0
  156. data/app/views/geo_works/related/_new_child_member.html.erb +22 -0
  157. data/app/views/geo_works/related/_new_parent_member.html.erb +13 -0
  158. data/app/views/geo_works/related/_parent_member.html.erb +13 -0
  159. data/app/views/geo_works/related/_parent_works.html.erb +22 -0
  160. data/app/views/hyrax/image_works/_file_actions.html.erb +8 -0
  161. data/app/views/hyrax/image_works/_form.html.erb +16 -0
  162. data/app/views/hyrax/image_works/_image_actions.html.erb +11 -0
  163. data/app/views/hyrax/image_works/_image_work.html.erb +2 -0
  164. data/app/views/hyrax/image_works/_show_actions.html.erb +22 -0
  165. data/app/views/hyrax/image_works/show.html.erb +31 -0
  166. data/app/views/hyrax/raster_works/_file_actions.html.erb +8 -0
  167. data/app/views/hyrax/raster_works/_form.html.erb +16 -0
  168. data/app/views/hyrax/raster_works/_raster_actions.html.erb +11 -0
  169. data/app/views/hyrax/raster_works/_raster_work.html.erb +2 -0
  170. data/app/views/hyrax/raster_works/_show_actions.html.erb +22 -0
  171. data/app/views/hyrax/raster_works/show.html.erb +31 -0
  172. data/app/views/hyrax/vector_works/_file_actions.html.erb +8 -0
  173. data/app/views/hyrax/vector_works/_form.html.erb +16 -0
  174. data/app/views/hyrax/vector_works/_show_actions.html.erb +22 -0
  175. data/app/views/hyrax/vector_works/_vector_actions.html.erb +11 -0
  176. data/app/views/hyrax/vector_works/_vector_work.html.erb +2 -0
  177. data/app/views/hyrax/vector_works/show.html.erb +31 -0
  178. data/app/views/records/edit_fields/_coverage.html.erb +3 -0
  179. data/app/views/records/edit_fields/_should_populate_metadata.html.erb +10 -0
  180. data/app/vocabs/geo_works/geo_terms.rb +12 -0
  181. data/config/discovery/geoblacklight-schema.json +214 -0
  182. data/config/fcrepo_wrapper_test.yml +3 -0
  183. data/config/geoblacklight.yml +12 -0
  184. data/config/geoserver.yml +27 -0
  185. data/config/initializers/geo_server.rb +17 -0
  186. data/config/initializers/geoblacklight_config.rb +18 -0
  187. data/config/initializers/simpler_tiles.rb +65 -0
  188. data/config/locales/image_work.en.yml +8 -0
  189. data/config/locales/raster_work.en.yml +8 -0
  190. data/config/locales/vector_work.en.yml +8 -0
  191. data/config/routes.rb +24 -0
  192. data/config/simpler_tiles.yml +24 -0
  193. data/config/solr_wrapper_test.yml +7 -0
  194. data/docker-compose-full.yml +30 -0
  195. data/docker-compose.yml +9 -0
  196. data/geo_works.gemspec +44 -0
  197. data/lib/generators/geo_works/install_generator.rb +152 -0
  198. data/lib/generators/geo_works/templates/actors/hyrax/actors/image_work_actor.rb +6 -0
  199. data/lib/generators/geo_works/templates/actors/hyrax/actors/raster_work_actor.rb +6 -0
  200. data/lib/generators/geo_works/templates/actors/hyrax/actors/vector_work_actor.rb +6 -0
  201. data/lib/generators/geo_works/templates/config/authorities/image_formats.yml +7 -0
  202. data/lib/generators/geo_works/templates/config/authorities/metadata_formats.yml +7 -0
  203. data/lib/generators/geo_works/templates/config/authorities/raster_formats.yml +13 -0
  204. data/lib/generators/geo_works/templates/config/authorities/vector_formats.yml +7 -0
  205. data/lib/generators/geo_works/templates/config/initializers/hyrax_derivative_path_monkey_patch.rb +18 -0
  206. data/lib/generators/geo_works/templates/controllers/hyrax/file_sets_controller.rb +7 -0
  207. data/lib/generators/geo_works/templates/controllers/hyrax/image_works_controller.rb +7 -0
  208. data/lib/generators/geo_works/templates/controllers/hyrax/raster_works_controller.rb +8 -0
  209. data/lib/generators/geo_works/templates/controllers/hyrax/vector_works_controller.rb +8 -0
  210. data/lib/generators/geo_works/templates/geo_works.js +1 -0
  211. data/lib/generators/geo_works/templates/geo_works.scss +3 -0
  212. data/lib/generators/geo_works/templates/models/file_set.rb +4 -0
  213. data/lib/generators/geo_works/templates/models/image_work.rb +7 -0
  214. data/lib/generators/geo_works/templates/models/raster_work.rb +8 -0
  215. data/lib/generators/geo_works/templates/models/vector_work.rb +8 -0
  216. data/lib/generators/geo_works/templates/presenters/file_set_presenter.rb +3 -0
  217. data/lib/generators/geo_works/templates/spec/actor_spec.rb.erb +9 -0
  218. data/lib/generators/geo_works/templates/spec/controller_spec.rb.erb +9 -0
  219. data/lib/generators/geo_works/templates/spec/model_spec.rb.erb +9 -0
  220. data/lib/geo_works.rb +9 -0
  221. data/lib/geo_works/engine.rb +4 -0
  222. data/lib/geo_works/version.rb +3 -0
  223. data/lib/tasks/geo_works_tasks.rake +4 -0
  224. data/run-docker.sh +16 -0
  225. data/solr/config/_rest_managed.json +3 -0
  226. data/solr/config/admin-extra.html +31 -0
  227. data/solr/config/elevate.xml +36 -0
  228. data/solr/config/mapping-ISOLatin1Accent.txt +246 -0
  229. data/solr/config/protwords.txt +21 -0
  230. data/solr/config/schema.xml +372 -0
  231. data/solr/config/scripts.conf +24 -0
  232. data/solr/config/solrconfig.xml +321 -0
  233. data/solr/config/spellings.txt +2 -0
  234. data/solr/config/stopwords.txt +58 -0
  235. data/solr/config/stopwords_en.txt +58 -0
  236. data/solr/config/synonyms.txt +31 -0
  237. data/solr/config/xslt/example.xsl +132 -0
  238. data/solr/config/xslt/example_atom.xsl +67 -0
  239. data/solr/config/xslt/example_rss.xsl +66 -0
  240. data/solr/config/xslt/luke.xsl +337 -0
  241. data/spec/controllers/file_sets_controller_spec.rb +70 -0
  242. data/spec/controllers/image_works_controller_spec.rb +40 -0
  243. data/spec/controllers/raster_works_controller_spec.rb +36 -0
  244. data/spec/controllers/vector_works_controller_spec.rb +69 -0
  245. data/spec/factories/collections.rb +17 -0
  246. data/spec/factories/external_metadata_files.rb +20 -0
  247. data/spec/factories/image_files.rb +32 -0
  248. data/spec/factories/image_works.rb +69 -0
  249. data/spec/factories/permission_templates.rb +41 -0
  250. data/spec/factories/raster_files.rb +35 -0
  251. data/spec/factories/raster_works.rb +88 -0
  252. data/spec/factories/sipity_entities.rb +7 -0
  253. data/spec/factories/users.rb +26 -0
  254. data/spec/factories/vector_files.rb +31 -0
  255. data/spec/factories/vector_works.rb +84 -0
  256. data/spec/factories/workflow_states.rb +6 -0
  257. data/spec/factories/workflows.rb +6 -0
  258. data/spec/features/create_image_work_spec.rb +34 -0
  259. data/spec/features/create_raster_work_spec.rb +35 -0
  260. data/spec/features/create_vector_work_spec.rb +34 -0
  261. data/spec/features/image_work_show_spec.rb +62 -0
  262. data/spec/features/raster_work_show_spec.rb +62 -0
  263. data/spec/features/vector_work_show_spec.rb +61 -0
  264. data/spec/forms/geo_works/basic_geo_metadata_form_spec.rb +31 -0
  265. data/spec/forms/geo_works/external_metadata_file_form_spec.rb +30 -0
  266. data/spec/forms/geo_works/georeferenced_form_spec.rb +33 -0
  267. data/spec/forms/hyrax/image_work_form_spec.rb +11 -0
  268. data/spec/forms/hyrax/raster_work_form_spec.rb +17 -0
  269. data/spec/forms/hyrax/vector_work_form_spec.rb +17 -0
  270. data/spec/helpers/bounding_box_helper_spec.rb +39 -0
  271. data/spec/helpers/geo_works/file_set_actions_helper_spec.rb +70 -0
  272. data/spec/helpers/geo_works/populate_metadata_helper_spec.rb +31 -0
  273. data/spec/helpers/geo_works_helper_spec.rb +30 -0
  274. data/spec/jobs/geoblacklight_job_spec.rb +18 -0
  275. data/spec/jobs/geoserver_delivery_job_spec.rb +45 -0
  276. data/spec/models/concerns/basic_geo_metadata_spec.rb +21 -0
  277. data/spec/models/concerns/geo_works/file_set/derivatives_spec.rb +102 -0
  278. data/spec/models/concerns/geo_works/file_set/geo_file_format_behavior_spec.rb +56 -0
  279. data/spec/models/external_metadata_file_spec.rb +118 -0
  280. data/spec/models/file_set_spec.rb +9 -0
  281. data/spec/models/image_file_spec.rb +48 -0
  282. data/spec/models/image_work_spec.rb +71 -0
  283. data/spec/models/raster_file_spec.rb +48 -0
  284. data/spec/models/raster_work_spec.rb +122 -0
  285. data/spec/models/solr_document_spec.rb +41 -0
  286. data/spec/models/vector_file_spec.rb +48 -0
  287. data/spec/models/vector_work_spec.rb +109 -0
  288. data/spec/presenters/file_set_presenter_spec.rb +13 -0
  289. data/spec/presenters/geo_works_show_presenter_spec.rb +46 -0
  290. data/spec/presenters/image_work_show_presenter_spec.rb +51 -0
  291. data/spec/presenters/raster_work_show_presenter_spec.rb +74 -0
  292. data/spec/presenters/vector_work_show_presenter_spec.rb +41 -0
  293. data/spec/processors/geo_works/geoblacklight_event_processor_spec.rb +80 -0
  294. data/spec/processors/geo_works/processors/base_geo_processor_spec.rb +115 -0
  295. data/spec/processors/geo_works/processors/gdal_spec.rb +59 -0
  296. data/spec/processors/geo_works/processors/image_spec.rb +64 -0
  297. data/spec/processors/geo_works/processors/ogr_spec.rb +36 -0
  298. data/spec/processors/geo_works/processors/raster/aig_spec.rb +35 -0
  299. data/spec/processors/geo_works/processors/raster/base_spec.rb +54 -0
  300. data/spec/processors/geo_works/processors/raster/dem_spec.rb +30 -0
  301. data/spec/processors/geo_works/processors/raster/info_spec.rb +35 -0
  302. data/spec/processors/geo_works/processors/raster/processor_spec.rb +39 -0
  303. data/spec/processors/geo_works/processors/rendering_spec.rb +64 -0
  304. data/spec/processors/geo_works/processors/vector/base_spec.rb +54 -0
  305. data/spec/processors/geo_works/processors/vector/info_spec.rb +50 -0
  306. data/spec/processors/geo_works/processors/vector/processor_spec.rb +28 -0
  307. data/spec/processors/geo_works/processors/vector/shapefile_spec.rb +17 -0
  308. data/spec/processors/geo_works/processors/zip_spec.rb +39 -0
  309. data/spec/renderers/geo_works/coverage_renderer_spec.rb +21 -0
  310. data/spec/services/geo_works/delivery/geoserver_spec.rb +117 -0
  311. data/spec/services/geo_works/delivery_service_spec.rb +24 -0
  312. data/spec/services/geo_works/discovery/abstract_document_spec.rb +23 -0
  313. data/spec/services/geo_works/discovery/document_builder/basic_metadata_builder_spec.rb +35 -0
  314. data/spec/services/geo_works/discovery/document_builder/wxs_spec.rb +71 -0
  315. data/spec/services/geo_works/discovery/document_builder_spec.rb +220 -0
  316. data/spec/services/geo_works/discovery/geoblacklight_document_spec.rb +20 -0
  317. data/spec/services/geo_works/event_generator_spec.rb +18 -0
  318. data/spec/services/geo_works/events_generator/geoblacklight_event_generator_spec.rb +84 -0
  319. data/spec/services/geo_works/events_generator/geoserver_event_generator_spec.rb +22 -0
  320. data/spec/services/geo_works/raster_format_service_spec.rb +13 -0
  321. data/spec/services/hyrax/derivative_path_spec.rb +26 -0
  322. data/spec/spec_helper.rb +77 -0
  323. data/spec/support/backport_test.rb +14 -0
  324. data/spec/support/controllers/engine_helpers.rb +7 -0
  325. data/spec/support/database_cleaner.rb +18 -0
  326. data/spec/support/factory_girl.rb +3 -0
  327. data/spec/support/features.rb +14 -0
  328. data/spec/support/features/session_helpers.rb +40 -0
  329. data/spec/support/fixture_reader.rb +7 -0
  330. data/spec/support/helpers/controller_level_helpers.rb +27 -0
  331. data/spec/support/views/test_view_helpers.rb +10 -0
  332. data/spec/test_app_templates/lib/generators/test_app_generator.rb +24 -0
  333. data/spec/values/coverage_spec.rb +40 -0
  334. data/tasks/geo_works.rake +39 -0
  335. data/template.rb +10 -0
  336. metadata +789 -0
data/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # GeoWorks
2
+
3
+ Code: [![Build Status](https://img.shields.io/travis/geoconcerns/geo_works/master.svg)](https://travis-ci.org/geoconcerns/geo_works)
4
+ [![Coverage Status](https://img.shields.io/coveralls/projecthydra-labs/geo_works/master.svg)](https://coveralls.io/github/geoconcerns/geo_works?branch=master)
5
+ [![Code Climate](https://codeclimate.com/github/geoconcerns/geo_works/badges/gpa.svg)](https://codeclimate.com/github/geoconcerns/geo_works)
6
+
7
+ Docs: [![Documentation Status](https://inch-ci.org/github/geoconcerns/geo_works.svg?branch=master)](https://inch-ci.org/github/geoconcerns/geo_works)
8
+ [![API Docs](http://img.shields.io/badge/API-docs-blue.svg)](http://www.rubydoc.info/github/geoconcerns/geo_works)
9
+ [![Gem Version](https://img.shields.io/gem/v/geo_works.svg)](https://github.com/geoconcerns/geo_works/releases)
10
+
11
+ Rails engine that provides geospatial models for [Hyrax](http://hyrax.projecthydra.org/) repository applications.
12
+
13
+ * [Poster from Hydra Connect 2015](https://drive.google.com/file/d/0B5fLh2mc4FCbOUpWaTFOVmI4Nkk/view?pli=1)
14
+ * [Current GeoWorks diagram](https://wiki.duraspace.org/download/attachments/69012114/pcdm-geo-model.pdf?version=1&modificationDate=1463590066822&api=v2)
15
+
16
+
17
+ ## Dependencies
18
+
19
+ 1. Solr
20
+ 1. [Fedora Commons](http://www.fedora-commons.org/) digital repository
21
+ 1. A SQL RDBMS (MySQL, PostgreSQL), though **note** that SQLite will be used by default if you're looking to get up and running quickly
22
+ 1. [Redis](http://redis.io/), a key-value store
23
+ 1. [ImageMagick](http://www.imagemagick.org/) with JPEG-2000 support
24
+ 1. [GDAL](http://www.gdal.org/)
25
+ * You can install it on Mac OSX with `brew install gdal`.
26
+ * On Ubuntu, use `sudo apt-get install gdal-bin`.
27
+ 1. [GeoServer](http://geoserver.org/) (Optional)
28
+
29
+ ## Simple Tiles
30
+
31
+ GeoWorks requires the image generation library [Simple Tiles](http://propublica.github.io/simple-tiles/).
32
+
33
+ Mac OS X:
34
+
35
+ - Install via Homebrew: ```brew install simple-tiles```
36
+
37
+ Linux:
38
+
39
+ - Install dependencies:
40
+
41
+ ```
42
+ libgdal-dev
43
+ libcairo2-dev
44
+ libpango1.0-dev
45
+ ```
46
+
47
+ - Compile:
48
+
49
+ ```
50
+ $ git clone git@github.com:propublica/simple-tiles.git
51
+ $ cd simple-tiles
52
+ $ ./configure
53
+ $ make && make install
54
+ ```
55
+
56
+ ## Installation
57
+
58
+ Create and run a new GeoWorks application from a template:
59
+
60
+ ```
61
+ $ rails new app-name -m https://raw.githubusercontent.com/projecthydra-labs/geo_works/master/template.rb
62
+ $ cd app-name
63
+ $ rake hydra:server
64
+ ```
65
+
66
+ Add GeoWorks models to an existing Hyrax application:
67
+
68
+ 1. Add `gem 'geo_works'` to your Gemfile.
69
+ 1. `bundle install`
70
+ 1. `rails generate hyrax:install`
71
+ 1. `rails generate geo_works:install -f`
72
+
73
+ ## Development
74
+
75
+ 1. `bundle install`
76
+ 2. `rake engine_cart:generate`
77
+ 3. `rake geo_works:dev_servers`
78
+
79
+ ## Testing
80
+
81
+ 3. `rake ci`
82
+
83
+ To run tests separately:
84
+
85
+ ```
86
+ $ rake geo_works:test_servers
87
+ ```
88
+
89
+ Then, in another terminal window:
90
+
91
+ ```
92
+ $ rake spec
93
+ ```
94
+ To run a specific test:
95
+
96
+ ```bash
97
+ rspec spec/path/to/your_spec.rb:linenumber
98
+ ```
99
+
100
+ ## Running GeoServer for Development with Docker
101
+
102
+ ### MacOS
103
+
104
+ 1. Make sure you have docker engine, docker-machine, and docker-compose installed.
105
+ - Docker Toolbox: [https://www.docker.com/products/docker-toolbox](https://www.docker.com/products/docker-toolbox)
106
+
107
+ 1. Execute the following command in the geo_works directory:
108
+
109
+ ```
110
+ $ source ./run-docker.sh
111
+ ```
112
+ 1. To stop the server and remove port forwarding:
113
+
114
+ ```
115
+ $ docker-compose stop
116
+ $ killall ssh
117
+ ```
118
+
119
+ ### Linux
120
+
121
+ 1. Make sure you have docker engine and docker-compose installed.
122
+ - [https://docs.docker.com/engine/installation/linux/](https://docs.docker.com/engine/installation/linux/)
123
+ - [https://docs.docker.com/compose/install/](https://docs.docker.com/compose/install/)
124
+
125
+ 1. Execute the following commands in the geo_works directory:
126
+
127
+ ```
128
+ $ docker-compose up -d
129
+ ```
130
+
131
+ ## Running GeoServer for Development with Vagrant
132
+
133
+ 1. Make sure you have VirtualBox and Vagrant installed.
134
+ - [https://www.virtualbox.org/wiki/Downloads](https://www.virtualbox.org/wiki/Downloads)
135
+ - [https://www.vagrantup.com/docs/installation/](https://www.vagrantup.com/docs/installation/)
136
+ 1. Execute the following commands:
137
+
138
+ ```
139
+ $ git clone https://github.com/geoconcerns/geoserver-vagrant.git
140
+ $ cd geoserver-vagrant/
141
+ $ vagrant up
142
+
143
+ ```
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+ require 'engine_cart/rake_task'
7
+ require 'rspec/core/rake_task'
8
+ require 'rubocop/rake_task'
9
+ require 'active_fedora/rake_support'
10
+ require 'solr_wrapper/rake_task'
11
+
12
+ Dir.glob('tasks/*.rake').each { |r| import r }
13
+
14
+ Bundler::GemHelper.install_tasks
15
+
16
+ desc 'Run test suite'
17
+ task spec: ['geo_works:rspec']
18
+
19
+ desc 'Spin up Solr & Fedora and run the test suite'
20
+ task ci: ['geo_works:rubocop', 'engine_cart:generate'] do
21
+ Rake::Task['geo_works:spec'].invoke
22
+ end
23
+
24
+ task clean: 'engine_cart:clean'
25
+ task default: :ci
File without changes
@@ -0,0 +1,1056 @@
1
+ // Copyright (c) 2012 sa3m (https://github.com/sa3m)
2
+ // Copyright (c) 2013 Per Liedman
3
+ // All rights reserved.
4
+
5
+ // Redistribution and use in source and binary forms, with or without modification, are
6
+ // permitted provided that the following conditions are met:
7
+
8
+ // 1. Redistributions of source code must retain the above copyright notice, this list of
9
+ // conditions and the following disclaimer.
10
+
11
+ // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12
+ // of conditions and the following disclaimer in the documentation and/or other materials
13
+ // provided with the distribution.
14
+
15
+ // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
16
+ // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17
+ // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
18
+ // COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19
+ // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
+ // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
+ // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22
+ // TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+
25
+ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
26
+ (function (global){
27
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
28
+ Nominatim = require('./geocoders/nominatim')["class"];
29
+
30
+ module.exports = {
31
+ "class": L.Control.extend({
32
+ options: {
33
+ showResultIcons: false,
34
+ collapsed: true,
35
+ expand: 'click',
36
+ position: 'topright',
37
+ placeholder: 'Search...',
38
+ errorMessage: 'Nothing found.'
39
+ },
40
+
41
+ _callbackId: 0,
42
+
43
+ initialize: function (options) {
44
+ L.Util.setOptions(this, options);
45
+ if (!this.options.geocoder) {
46
+ this.options.geocoder = new Nominatim();
47
+ }
48
+ },
49
+
50
+ onAdd: function (map) {
51
+ var className = 'leaflet-control-geocoder',
52
+ container = L.DomUtil.create('div', className + ' leaflet-bar'),
53
+ icon = L.DomUtil.create('a', 'leaflet-control-geocoder-icon', container),
54
+ form = this._form = L.DomUtil.create('form', className + '-form', container),
55
+ input;
56
+
57
+ icon.innerHTML = '&nbsp;';
58
+ icon.href = 'javascript:void(0);';
59
+ this._map = map;
60
+ this._container = container;
61
+ input = this._input = L.DomUtil.create('input');
62
+ input.type = 'text';
63
+ input.placeholder = this.options.placeholder;
64
+
65
+ L.DomEvent.addListener(input, 'keydown', this._keydown, this);
66
+ //L.DomEvent.addListener(input, 'onpaste', this._clearResults, this);
67
+ //L.DomEvent.addListener(input, 'oninput', this._clearResults, this);
68
+
69
+ this._errorElement = document.createElement('div');
70
+ this._errorElement.className = className + '-form-no-error';
71
+ this._errorElement.innerHTML = this.options.errorMessage;
72
+
73
+ this._alts = L.DomUtil.create('ul', className + '-alternatives leaflet-control-geocoder-alternatives-minimized');
74
+
75
+ form.appendChild(input);
76
+ this._container.appendChild(this._errorElement);
77
+ container.appendChild(this._alts);
78
+
79
+ L.DomEvent.addListener(form, 'submit', this._geocode, this);
80
+
81
+ if (this.options.collapsed) {
82
+ if (this.options.expand === 'click') {
83
+ L.DomEvent.addListener(icon, 'click', function(e) {
84
+ // TODO: touch
85
+ if (e.button === 0 && e.detail !== 2) {
86
+ this._toggle();
87
+ }
88
+ }, this);
89
+ } else {
90
+ L.DomEvent.addListener(icon, 'mouseover', this._expand, this);
91
+ L.DomEvent.addListener(icon, 'mouseout', this._collapse, this);
92
+ this._map.on('movestart', this._collapse, this);
93
+ }
94
+ } else {
95
+ L.DomEvent.addListener(icon, 'click', function(e) {
96
+ this._geocode(e);
97
+ }, this);
98
+ this._expand();
99
+ }
100
+
101
+ L.DomEvent.disableClickPropagation(container);
102
+
103
+ return container;
104
+ },
105
+
106
+ _geocodeResult: function (results) {
107
+ L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
108
+ if (results.length === 1) {
109
+ this._geocodeResultSelected(results[0]);
110
+ } else if (results.length > 0) {
111
+ this._alts.innerHTML = '';
112
+ this._results = results;
113
+ L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
114
+ for (var i = 0; i < results.length; i++) {
115
+ this._alts.appendChild(this._createAlt(results[i], i));
116
+ }
117
+ } else {
118
+ L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
119
+ }
120
+ },
121
+
122
+ markGeocode: function(result) {
123
+ this._map.fitBounds(result.bbox);
124
+
125
+ if (this._geocodeMarker) {
126
+ this._map.removeLayer(this._geocodeMarker);
127
+ }
128
+
129
+ return this;
130
+ },
131
+
132
+ _geocode: function(event) {
133
+ L.DomEvent.preventDefault(event);
134
+
135
+ L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
136
+ this._clearResults();
137
+ this.options.geocoder.geocode(this._input.value, this._geocodeResult, this);
138
+
139
+ return false;
140
+ },
141
+
142
+ _geocodeResultSelected: function(result) {
143
+ if (this.options.collapsed) {
144
+ this._collapse();
145
+ } else {
146
+ this._clearResults();
147
+ }
148
+ this.markGeocode(result);
149
+ },
150
+
151
+ _toggle: function() {
152
+ if (this._container.className.indexOf('leaflet-control-geocoder-expanded') >= 0) {
153
+ this._collapse();
154
+ } else {
155
+ this._expand();
156
+ }
157
+ },
158
+
159
+ _expand: function () {
160
+ L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
161
+ this._input.select();
162
+ },
163
+
164
+ _collapse: function () {
165
+ this._container.className = this._container.className.replace(' leaflet-control-geocoder-expanded', '');
166
+ L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
167
+ L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
168
+ },
169
+
170
+ _clearResults: function () {
171
+ L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
172
+ this._selection = null;
173
+ L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
174
+ },
175
+
176
+ _createAlt: function(result, index) {
177
+ var li = L.DomUtil.create('li', ''),
178
+ a = L.DomUtil.create('a', '', li),
179
+ icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
180
+ text = result.html ? undefined : document.createTextNode(result.name),
181
+ clickHandler = function clickHandler(e) {
182
+ L.DomEvent.preventDefault(e);
183
+ this._geocodeResultSelected(result);
184
+ };
185
+
186
+ if (icon) {
187
+ icon.src = result.icon;
188
+ }
189
+
190
+ li.setAttribute('data-result-index', index);
191
+
192
+ if (result.html) {
193
+ a.innerHTML = result.html;
194
+ } else {
195
+ a.appendChild(text);
196
+ }
197
+
198
+ L.DomEvent.addListener(li, 'click', clickHandler, this);
199
+
200
+ return li;
201
+ },
202
+
203
+ _keydown: function(e) {
204
+ var _this = this,
205
+ select = function select(dir) {
206
+ if (_this._selection) {
207
+ L.DomUtil.removeClass(_this._selection, 'leaflet-control-geocoder-selected');
208
+ _this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
209
+ }
210
+ if (!_this._selection) {
211
+ _this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
212
+ }
213
+
214
+ if (_this._selection) {
215
+ L.DomUtil.addClass(_this._selection, 'leaflet-control-geocoder-selected');
216
+ }
217
+ };
218
+
219
+ switch (e.keyCode) {
220
+ // Escape
221
+ case 27:
222
+ if (this.options.collapsed) {
223
+ this._collapse();
224
+ }
225
+ break;
226
+ // Up
227
+ case 38:
228
+ select(-1);
229
+ L.DomEvent.preventDefault(e);
230
+ break;
231
+ // Up
232
+ case 40:
233
+ select(1);
234
+ L.DomEvent.preventDefault(e);
235
+ break;
236
+ // Enter
237
+ case 13:
238
+ if (this._selection) {
239
+ var index = parseInt(this._selection.getAttribute('data-result-index'), 10);
240
+ this._geocodeResultSelected(this._results[index]);
241
+ this._clearResults();
242
+ L.DomEvent.preventDefault(e);
243
+ }
244
+ }
245
+ return true;
246
+ }
247
+ }),
248
+ factory: function(options) {
249
+ return new L.Control.Geocoder(options);
250
+ }
251
+ };
252
+
253
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
254
+ },{"./geocoders/nominatim":7}],2:[function(require,module,exports){
255
+ (function (global){
256
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
257
+ Util = require('../util');
258
+
259
+ module.exports = {
260
+ "class": L.Class.extend({
261
+ initialize: function(key) {
262
+ this.key = key;
263
+ },
264
+
265
+ geocode : function (query, cb, context) {
266
+ Util.jsonp('//dev.virtualearth.net/REST/v1/Locations', {
267
+ query: query,
268
+ key : this.key
269
+ }, function(data) {
270
+ var results = [];
271
+ if( data.resourceSets.length > 0 ){
272
+ for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
273
+ var resource = data.resourceSets[0].resources[i],
274
+ bbox = resource.bbox;
275
+ results[i] = {
276
+ name: resource.name,
277
+ bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
278
+ center: L.latLng(resource.point.coordinates)
279
+ };
280
+ }
281
+ }
282
+ cb.call(context, results);
283
+ }, this, 'jsonp');
284
+ },
285
+
286
+ reverse: function(location, scale, cb, context) {
287
+ Util.jsonp('//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng, {
288
+ key : this.key
289
+ }, function(data) {
290
+ var results = [];
291
+ for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
292
+ var resource = data.resourceSets[0].resources[i],
293
+ bbox = resource.bbox;
294
+ results[i] = {
295
+ name: resource.name,
296
+ bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
297
+ center: L.latLng(resource.point.coordinates)
298
+ };
299
+ }
300
+ cb.call(context, results);
301
+ }, this, 'jsonp');
302
+ }
303
+ }),
304
+
305
+ factory: function(key) {
306
+ return new L.Control.Geocoder.Bing(key);
307
+ }
308
+ };
309
+
310
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
311
+ },{"../util":11}],3:[function(require,module,exports){
312
+ (function (global){
313
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
314
+ Util = require('../util');
315
+
316
+ module.exports = {
317
+ "class": L.Class.extend({
318
+ options: {
319
+ serviceUrl: 'https://maps.googleapis.com/maps/api/geocode/json',
320
+ geocodingQueryParams: {},
321
+ reverseQueryParams: {}
322
+ },
323
+
324
+ initialize: function(key, options) {
325
+ this._key = key;
326
+ L.setOptions(this, options);
327
+ // Backwards compatibility
328
+ this.options.serviceUrl = this.options.service_url || this.options.serviceUrl;
329
+ },
330
+
331
+ geocode: function(query, cb, context) {
332
+ var params = {
333
+ address: query
334
+ };
335
+
336
+ if (this._key && this._key.length) {
337
+ params.key = this._key;
338
+ }
339
+
340
+ params = L.Util.extend(params, this.options.geocodingQueryParams);
341
+
342
+ Util.getJSON(this.options.serviceUrl, params, function(data) {
343
+ var results = [],
344
+ loc,
345
+ latLng,
346
+ latLngBounds;
347
+ if (data.results && data.results.length) {
348
+ for (var i = 0; i <= data.results.length - 1; i++) {
349
+ loc = data.results[i];
350
+ latLng = L.latLng(loc.geometry.location);
351
+ latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
352
+ results[i] = {
353
+ name: loc.formatted_address,
354
+ bbox: latLngBounds,
355
+ center: latLng,
356
+ properties: loc.address_components
357
+ };
358
+ }
359
+ }
360
+
361
+ cb.call(context, results);
362
+ });
363
+ },
364
+
365
+ reverse: function(location, scale, cb, context) {
366
+ var params = {
367
+ latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
368
+ };
369
+ params = L.Util.extend(params, this.options.reverseQueryParams);
370
+ if (this._key && this._key.length) {
371
+ params.key = this._key;
372
+ }
373
+
374
+ Util.getJSON(this.options.serviceUrl, params, function(data) {
375
+ var results = [],
376
+ loc,
377
+ latLng,
378
+ latLngBounds;
379
+ if (data.results && data.results.length) {
380
+ for (var i = 0; i <= data.results.length - 1; i++) {
381
+ loc = data.results[i];
382
+ latLng = L.latLng(loc.geometry.location);
383
+ latLngBounds = L.latLngBounds(L.latLng(loc.geometry.viewport.northeast), L.latLng(loc.geometry.viewport.southwest));
384
+ results[i] = {
385
+ name: loc.formatted_address,
386
+ bbox: latLngBounds,
387
+ center: latLng,
388
+ properties: loc.address_components
389
+ };
390
+ }
391
+ }
392
+
393
+ cb.call(context, results);
394
+ });
395
+ }
396
+ }),
397
+
398
+ factory: function(key, options) {
399
+ return new L.Control.Geocoder.Google(key, options);
400
+ }
401
+ };
402
+
403
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
404
+ },{"../util":11}],4:[function(require,module,exports){
405
+ (function (global){
406
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
407
+ Util = require('../util');
408
+
409
+ module.exports = {
410
+ "class": L.Class.extend({
411
+ options: {
412
+ serviceUrl: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/'
413
+ },
414
+
415
+ initialize: function(accessToken, options) {
416
+ L.setOptions(this, options);
417
+ this._accessToken = accessToken;
418
+ },
419
+
420
+ geocode: function(query, cb, context) {
421
+ Util.getJSON(this.options.serviceUrl + encodeURIComponent(query) + '.json', {
422
+ access_token: this._accessToken
423
+ }, function(data) {
424
+ var results = [],
425
+ loc,
426
+ latLng,
427
+ latLngBounds;
428
+ if (data.features && data.features.length) {
429
+ for (var i = 0; i <= data.features.length - 1; i++) {
430
+ loc = data.features[i];
431
+ latLng = L.latLng(loc.center.reverse());
432
+ if(loc.hasOwnProperty('bbox'))
433
+ {
434
+ latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
435
+ }
436
+ else
437
+ {
438
+ latLngBounds = L.latLngBounds(latLng, latLng);
439
+ }
440
+ results[i] = {
441
+ name: loc.place_name,
442
+ bbox: latLngBounds,
443
+ center: latLng
444
+ };
445
+ }
446
+ }
447
+
448
+ cb.call(context, results);
449
+ });
450
+ },
451
+
452
+ suggest: function(query, cb, context) {
453
+ return this.geocode(query, cb, context);
454
+ },
455
+
456
+ reverse: function(location, scale, cb, context) {
457
+ Util.getJSON(this.options.serviceUrl + encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat) + '.json', {
458
+ access_token: this._accessToken
459
+ }, function(data) {
460
+ var results = [],
461
+ loc,
462
+ latLng,
463
+ latLngBounds;
464
+ if (data.features && data.features.length) {
465
+ for (var i = 0; i <= data.features.length - 1; i++) {
466
+ loc = data.features[i];
467
+ latLng = L.latLng(loc.center.reverse());
468
+ if(loc.hasOwnProperty('bbox'))
469
+ {
470
+ latLngBounds = L.latLngBounds(L.latLng(loc.bbox.slice(0, 2).reverse()), L.latLng(loc.bbox.slice(2, 4).reverse()));
471
+ }
472
+ else
473
+ {
474
+ latLngBounds = L.latLngBounds(latLng, latLng);
475
+ }
476
+ results[i] = {
477
+ name: loc.place_name,
478
+ bbox: latLngBounds,
479
+ center: latLng
480
+ };
481
+ }
482
+ }
483
+
484
+ cb.call(context, results);
485
+ });
486
+ }
487
+ }),
488
+
489
+ factory: function(accessToken, options) {
490
+ return new L.Control.Geocoder.Mapbox(accessToken, options);
491
+ }
492
+ };
493
+
494
+
495
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
496
+ },{"../util":11}],5:[function(require,module,exports){
497
+ (function (global){
498
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
499
+ Util = require('../util');
500
+
501
+ module.exports = {
502
+ "class": L.Class.extend({
503
+ options: {
504
+ serviceUrl: '//www.mapquestapi.com/geocoding/v1'
505
+ },
506
+
507
+ initialize: function(key, options) {
508
+ // MapQuest seems to provide URI encoded API keys,
509
+ // so to avoid encoding them twice, we decode them here
510
+ this._key = decodeURIComponent(key);
511
+
512
+ L.Util.setOptions(this, options);
513
+ },
514
+
515
+ _formatName: function() {
516
+ var r = [],
517
+ i;
518
+ for (i = 0; i < arguments.length; i++) {
519
+ if (arguments[i]) {
520
+ r.push(arguments[i]);
521
+ }
522
+ }
523
+
524
+ return r.join(', ');
525
+ },
526
+
527
+ geocode: function(query, cb, context) {
528
+ Util.jsonp(this.options.serviceUrl + '/address', {
529
+ key: this._key,
530
+ location: query,
531
+ limit: 5,
532
+ outFormat: 'json'
533
+ }, function(data) {
534
+ var results = [],
535
+ loc,
536
+ latLng;
537
+ if (data.results && data.results[0].locations) {
538
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
539
+ loc = data.results[0].locations[i];
540
+ latLng = L.latLng(loc.latLng);
541
+ results[i] = {
542
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
543
+ bbox: L.latLngBounds(latLng, latLng),
544
+ center: latLng
545
+ };
546
+ }
547
+ }
548
+
549
+ cb.call(context, results);
550
+ }, this);
551
+ },
552
+
553
+ reverse: function(location, scale, cb, context) {
554
+ Util.jsonp(this.options.serviceUrl + '/reverse', {
555
+ key: this._key,
556
+ location: location.lat + ',' + location.lng,
557
+ outputFormat: 'json'
558
+ }, function(data) {
559
+ var results = [],
560
+ loc,
561
+ latLng;
562
+ if (data.results && data.results[0].locations) {
563
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
564
+ loc = data.results[0].locations[i];
565
+ latLng = L.latLng(loc.latLng);
566
+ results[i] = {
567
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
568
+ bbox: L.latLngBounds(latLng, latLng),
569
+ center: latLng
570
+ };
571
+ }
572
+ }
573
+
574
+ cb.call(context, results);
575
+ }, this);
576
+ }
577
+ }),
578
+
579
+ factory: function(key, options) {
580
+ return new L.Control.Geocoder.MapQuest(key, options);
581
+ }
582
+ };
583
+
584
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
585
+ },{"../util":11}],6:[function(require,module,exports){
586
+ (function (global){
587
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
588
+ Util = require('../util');
589
+
590
+ module.exports = {
591
+ "class": L.Class.extend({
592
+ options: {
593
+ serviceUrl: '//search.mapzen.com/v1',
594
+ geocodingQueryParams: {},
595
+ reverseQueryParams: {}
596
+ },
597
+
598
+ initialize: function(apiKey, options) {
599
+ L.Util.setOptions(this, options);
600
+ this._apiKey = apiKey;
601
+ this._lastSuggest = 0;
602
+ },
603
+
604
+ geocode: function(query, cb, context) {
605
+ var _this = this;
606
+ Util.getJSON(this.options.serviceUrl + "/search", L.extend({
607
+ 'api_key': this._apiKey,
608
+ 'text': query
609
+ }, this.options.geocodingQueryParams), function(data) {
610
+ cb.call(context, _this._parseResults(data, "bbox"));
611
+ });
612
+ },
613
+
614
+ suggest: function(query, cb, context) {
615
+ var _this = this;
616
+ Util.getJSON(this.options.serviceUrl + "/autocomplete", L.extend({
617
+ 'api_key': this._apiKey,
618
+ 'text': query
619
+ }, this.options.geocodingQueryParams), function(data) {
620
+ if (data.geocoding.timestamp > this._lastSuggest) {
621
+ this._lastSuggest = data.geocoding.timestamp;
622
+ cb.call(context, _this._parseResults(data, "bbox"));
623
+ }
624
+ });
625
+ },
626
+
627
+ reverse: function(location, scale, cb, context) {
628
+ var _this = this;
629
+ Util.getJSON(this.options.serviceUrl + "/reverse", L.extend({
630
+ 'api_key': this._apiKey,
631
+ 'point.lat': location.lat,
632
+ 'point.lon': location.lng
633
+ }, this.options.reverseQueryParams), function(data) {
634
+ cb.call(context, _this._parseResults(data, "bounds"));
635
+ });
636
+ },
637
+
638
+ _parseResults: function(data, bboxname) {
639
+ var results = [];
640
+ L.geoJson(data, {
641
+ pointToLayer: function (feature, latlng) {
642
+ return L.circleMarker(latlng);
643
+ },
644
+ onEachFeature: function(feature, layer) {
645
+ var result = {};
646
+ result['name'] = layer.feature.properties.label;
647
+ result[bboxname] = layer.getBounds();
648
+ result['center'] = result[bboxname].getCenter();
649
+ result['properties'] = layer.feature.properties;
650
+ results.push(result);
651
+ }
652
+ });
653
+ return results;
654
+ }
655
+ }),
656
+
657
+ factory: function(apiKey, options) {
658
+ return new L.Control.Geocoder.Mapzen(apiKey, options);
659
+ }
660
+ };
661
+
662
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
663
+ },{"../util":11}],7:[function(require,module,exports){
664
+ (function (global){
665
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
666
+ Util = require('../util');
667
+
668
+ module.exports = {
669
+ "class": L.Class.extend({
670
+ options: {
671
+ serviceUrl: '//nominatim.openstreetmap.org/',
672
+ geocodingQueryParams: {},
673
+ reverseQueryParams: {},
674
+ htmlTemplate: function(r) {
675
+ var a = r.address,
676
+ parts = [];
677
+ if (a.road || a.building) {
678
+ parts.push('{building} {road} {house_number}');
679
+ }
680
+
681
+ if (a.city || a.town || a.village) {
682
+ parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-detail' : '') +
683
+ '">{postcode} {city} {town} {village}</span>');
684
+ }
685
+
686
+ if (a.state || a.country) {
687
+ parts.push('<span class="' + (parts.length > 0 ? 'leaflet-control-geocoder-address-context' : '') +
688
+ '">{state} {country}</span>');
689
+ }
690
+
691
+ return Util.template(parts.join('<br/>'), a, true);
692
+ }
693
+ },
694
+
695
+ initialize: function(options) {
696
+ L.Util.setOptions(this, options);
697
+ },
698
+
699
+ geocode: function(query, cb, context) {
700
+ Util.jsonp(this.options.serviceUrl + 'search', L.extend({
701
+ q: query,
702
+ limit: 5,
703
+ format: 'json',
704
+ addressdetails: 1
705
+ }, this.options.geocodingQueryParams),
706
+ function(data) {
707
+ var results = [];
708
+ for (var i = data.length - 1; i >= 0; i--) {
709
+ var bbox = data[i].boundingbox;
710
+ for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
711
+ results[i] = {
712
+ icon: data[i].icon,
713
+ name: data[i].display_name,
714
+ html: this.options.htmlTemplate ?
715
+ this.options.htmlTemplate(data[i])
716
+ : undefined,
717
+ bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
718
+ center: L.latLng(data[i].lat, data[i].lon),
719
+ properties: data[i]
720
+ };
721
+ }
722
+ cb.call(context, results);
723
+ }, this, 'json_callback');
724
+ },
725
+
726
+ reverse: function(location, scale, cb, context) {
727
+ Util.jsonp(this.options.serviceUrl + 'reverse', L.extend({
728
+ lat: location.lat,
729
+ lon: location.lng,
730
+ zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
731
+ addressdetails: 1,
732
+ format: 'json'
733
+ }, this.options.reverseQueryParams), function(data) {
734
+ var result = [],
735
+ loc;
736
+
737
+ if (data && data.lat && data.lon) {
738
+ loc = L.latLng(data.lat, data.lon);
739
+ result.push({
740
+ name: data.display_name,
741
+ html: this.options.htmlTemplate ?
742
+ this.options.htmlTemplate(data)
743
+ : undefined,
744
+ center: loc,
745
+ bounds: L.latLngBounds(loc, loc),
746
+ properties: data
747
+ });
748
+ }
749
+
750
+ cb.call(context, result);
751
+ }, this, 'json_callback');
752
+ }
753
+ }),
754
+
755
+ factory: function(options) {
756
+ return new L.Control.Geocoder.Nominatim(options);
757
+ }
758
+ };
759
+
760
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
761
+ },{"../util":11}],8:[function(require,module,exports){
762
+ (function (global){
763
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
764
+ Util = require('../util');
765
+
766
+ module.exports = {
767
+ "class": L.Class.extend({
768
+ options: {
769
+ serviceUrl: '//photon.komoot.de/api/',
770
+ reverseUrl: '//photon.komoot.de/reverse/',
771
+ nameProperties: [
772
+ 'name',
773
+ 'street',
774
+ 'suburb',
775
+ 'hamlet',
776
+ 'town',
777
+ 'city',
778
+ 'state',
779
+ 'country'
780
+ ]
781
+ },
782
+
783
+ initialize: function(options) {
784
+ L.setOptions(this, options);
785
+ },
786
+
787
+ geocode: function(query, cb, context) {
788
+ var params = L.extend({
789
+ q: query
790
+ }, this.options.geocodingQueryParams);
791
+
792
+ Util.getJSON(this.options.serviceUrl, params, L.bind(function(data) {
793
+ cb.call(context, this._decodeFeatures(data));
794
+ }, this));
795
+ },
796
+
797
+ suggest: function(query, cb, context) {
798
+ return this.geocode(query, cb, context);
799
+ },
800
+
801
+ reverse: function(latLng, scale, cb, context) {
802
+ var params = L.extend({
803
+ lat: latLng.lat,
804
+ lon: latLng.lng
805
+ }, this.options.geocodingQueryParams);
806
+
807
+ Util.getJSON(this.options.reverseUrl, params, L.bind(function(data) {
808
+ cb.call(context, this._decodeFeatures(data));
809
+ }, this));
810
+ },
811
+
812
+ _decodeFeatures: function(data) {
813
+ var results = [],
814
+ i,
815
+ f,
816
+ c,
817
+ latLng,
818
+ extent,
819
+ bbox;
820
+
821
+ if (data && data.features) {
822
+ for (i = 0; i < data.features.length; i++) {
823
+ f = data.features[i];
824
+ c = f.geometry.coordinates;
825
+ latLng = L.latLng(c[1], c[0]);
826
+ extent = f.properties.extent;
827
+
828
+ if (extent) {
829
+ bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]);
830
+ } else {
831
+ bbox = L.latLngBounds(latLng, latLng);
832
+ }
833
+
834
+ results.push({
835
+ name: this._deocodeFeatureName(f),
836
+ center: latLng,
837
+ bbox: bbox,
838
+ properties: f.properties
839
+ });
840
+ }
841
+ }
842
+
843
+ return results;
844
+ },
845
+
846
+ _deocodeFeatureName: function(f) {
847
+ var j,
848
+ name;
849
+ for (j = 0; !name && j < this.options.nameProperties.length; j++) {
850
+ name = f.properties[this.options.nameProperties[j]];
851
+ }
852
+
853
+ return name;
854
+ }
855
+ }),
856
+
857
+ factory: function(options) {
858
+ return new L.Control.Geocoder.Photon(options);
859
+ }
860
+ };
861
+
862
+
863
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
864
+ },{"../util":11}],9:[function(require,module,exports){
865
+ (function (global){
866
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
867
+ Util = require('../util');
868
+
869
+ module.exports = {
870
+ "class": L.Class.extend({
871
+ options: {
872
+ serviceUrl: 'http://api.what3words.com/'
873
+ },
874
+
875
+ initialize: function(accessToken) {
876
+ this._accessToken = accessToken;
877
+ },
878
+
879
+ geocode: function(query, cb, context) {
880
+ //get three words and make a dot based string
881
+ Util.getJSON(this.options.serviceUrl +'w3w', {
882
+ key: this._accessToken,
883
+ string: query.split(/\s+/).join('.')
884
+ }, function(data) {
885
+ var results = [], loc, latLng, latLngBounds;
886
+ if (data.position && data.position.length) {
887
+ loc = data.words;
888
+ latLng = L.latLng(data.position[0],data.position[1]);
889
+ latLngBounds = L.latLngBounds(latLng, latLng);
890
+ results[0] = {
891
+ name: loc.join('.'),
892
+ bbox: latLngBounds,
893
+ center: latLng
894
+ };
895
+ }
896
+
897
+ cb.call(context, results);
898
+ });
899
+ },
900
+
901
+ suggest: function(query, cb, context) {
902
+ return this.geocode(query, cb, context);
903
+ },
904
+
905
+ reverse: function(location, scale, cb, context) {
906
+ Util.getJSON(this.options.serviceUrl +'position', {
907
+ key: this._accessToken,
908
+ position: [location.lat,location.lng].join(',')
909
+ }, function(data) {
910
+ var results = [],loc,latLng,latLngBounds;
911
+ if (data.position && data.position.length) {
912
+ loc = data.words;
913
+ latLng = L.latLng(data.position[0],data.position[1]);
914
+ latLngBounds = L.latLngBounds(latLng, latLng);
915
+ results[0] = {
916
+ name: loc.join('.'),
917
+ bbox: latLngBounds,
918
+ center: latLng
919
+ };
920
+ }
921
+ cb.call(context, results);
922
+ });
923
+ }
924
+ }),
925
+
926
+ factory: function(accessToken) {
927
+ return new L.Control.Geocoder.What3Words(accessToken);
928
+ }
929
+ };
930
+
931
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
932
+ },{"../util":11}],10:[function(require,module,exports){
933
+ (function (global){
934
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
935
+ Control = require('./control'),
936
+ Nominatim = require('./geocoders/nominatim'),
937
+ Bing = require('./geocoders/bing'),
938
+ MapQuest = require('./geocoders/mapquest'),
939
+ Mapbox = require('./geocoders/mapbox'),
940
+ What3Words = require('./geocoders/what3words'),
941
+ Google = require('./geocoders/google'),
942
+ Photon = require('./geocoders/photon'),
943
+ Mapzen = require('./geocoders/mapzen');
944
+
945
+ module.exports = L.Util.extend(Control["class"], {
946
+ Nominatim: Nominatim["class"],
947
+ nominatim: Nominatim.factory,
948
+ Bing: Bing["class"],
949
+ bing: Bing.factory,
950
+ MapQuest: MapQuest["class"],
951
+ mapQuest: MapQuest.factory,
952
+ Mapbox: Mapbox["class"],
953
+ mapbox: Mapbox.factory,
954
+ What3Words: What3Words["class"],
955
+ what3words: What3Words.factory,
956
+ Google: Google["class"],
957
+ google: Google.factory,
958
+ Photon: Photon["class"],
959
+ photon: Photon.factory,
960
+ Mapzen: Mapzen["class"],
961
+ mapzen: Mapzen.factory
962
+ });
963
+
964
+ L.Util.extend(L.Control, {
965
+ Geocoder: module.exports,
966
+ geocoder: Control.factory
967
+ });
968
+
969
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
970
+ },{"./control":1,"./geocoders/bing":2,"./geocoders/google":3,"./geocoders/mapbox":4,"./geocoders/mapquest":5,"./geocoders/mapzen":6,"./geocoders/nominatim":7,"./geocoders/photon":8,"./geocoders/what3words":9}],11:[function(require,module,exports){
971
+ (function (global){
972
+ var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null),
973
+ lastCallbackId = 0,
974
+ htmlEscape = (function() {
975
+ // Adapted from handlebars.js
976
+ // https://github.com/wycats/handlebars.js/
977
+ var badChars = /[&<>"'`]/g;
978
+ var possible = /[&<>"'`]/;
979
+ var escape = {
980
+ '&': '&amp;',
981
+ '<': '&lt;',
982
+ '>': '&gt;',
983
+ '"': '&quot;',
984
+ '\'': '&#x27;',
985
+ '`': '&#x60;'
986
+ };
987
+
988
+ function escapeChar(chr) {
989
+ return escape[chr];
990
+ }
991
+
992
+ return function(string) {
993
+ if (string == null) {
994
+ return '';
995
+ } else if (!string) {
996
+ return string + '';
997
+ }
998
+
999
+ // Force a string conversion as this will be done by the append regardless and
1000
+ // the regex test will do this transparently behind the scenes, causing issues if
1001
+ // an object's to string has escaped characters in it.
1002
+ string = '' + string;
1003
+
1004
+ if (!possible.test(string)) {
1005
+ return string;
1006
+ }
1007
+ return string.replace(badChars, escapeChar);
1008
+ };
1009
+ })();
1010
+
1011
+ module.exports = {
1012
+ jsonp: function(url, params, callback, context, jsonpParam) {
1013
+ var callbackId = '_l_geocoder_' + (lastCallbackId++);
1014
+ params[jsonpParam || 'callback'] = callbackId;
1015
+ window[callbackId] = L.Util.bind(callback, context);
1016
+ var script = document.createElement('script');
1017
+ script.type = 'text/javascript';
1018
+ script.src = url + L.Util.getParamString(params);
1019
+ script.id = callbackId;
1020
+ document.getElementsByTagName('head')[0].appendChild(script);
1021
+ },
1022
+
1023
+ getJSON: function(url, params, callback) {
1024
+ var xmlHttp = new XMLHttpRequest();
1025
+ xmlHttp.onreadystatechange = function () {
1026
+ if (xmlHttp.readyState !== 4){
1027
+ return;
1028
+ }
1029
+ if (xmlHttp.status !== 200 && xmlHttp.status !== 304){
1030
+ callback('');
1031
+ return;
1032
+ }
1033
+ callback(JSON.parse(xmlHttp.response));
1034
+ };
1035
+ xmlHttp.open('GET', url + L.Util.getParamString(params), true);
1036
+ xmlHttp.setRequestHeader('Accept', 'application/json');
1037
+ xmlHttp.send(null);
1038
+ },
1039
+
1040
+ template: function (str, data) {
1041
+ return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
1042
+ var value = data[key];
1043
+ if (value === undefined) {
1044
+ value = '';
1045
+ } else if (typeof value === 'function') {
1046
+ value = value(data);
1047
+ }
1048
+ return htmlEscape(value);
1049
+ });
1050
+ },
1051
+
1052
+ htmlEscape: htmlEscape
1053
+ };
1054
+
1055
+ }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1056
+ },{}]},{},[10]);