Skip to content

Commit

Permalink
Chores/fix map (#43)
Browse files Browse the repository at this point in the history
* Fix dependencies

* Remove useless method

* Fist version

* improve lib and repair existing data

* Change destination format

* Fix readme

* Fix tests

* Add more tests

* Add convert to commands

* Remove unused js

* Add dep to module

* Fix offenses

* Install proj

* Add debugger

* Add dep

* Add new config

* Pristine dep

* Clean workflow

* Update config

* Remove unused test

* Update apt cache

* Pin dep

* Add dep

* Add readme

* Setup cache action

* Update readme

* Debug

* Setup concurrency level

* reconstruct shared object cache after build

* Add custom matcher

* remove debug

* Remove useless file

* Add debug

* Recompile with cache

* Use env var

* Fix missing require

* Symbolize keys

* Complete readme
  • Loading branch information
armandfardeau authored Feb 6, 2023
1 parent 3710b53 commit 0e80a82
Show file tree
Hide file tree
Showing 20 changed files with 631 additions and 73 deletions.
17 changes: 17 additions & 0 deletions .github/install_proj.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
sudo apt-get update && sudo apt install cmake sqlite libtiff-dev curl libcurl4-openssl-dev libssl-dev -y

if [ ! -d "$PROJ_VERSION" ]; then
curl https://download.osgeo.org/proj/"${PROJ_VERSION}".tar.gz -o "${PROJ_VERSION}".tar.gz
tar -xzf "${PROJ_VERSION}".tar.gz
fi

cd "$PROJ_VERSION" || exit

if [ ! -d "build" ]; then
mkdir build
fi

cd build || exit
cmake ..
sudo cmake --build . -j "$(nproc)" --target install
sudo ldconfig
13 changes: 13 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ env:
CI: "true"
CODECOV: "true"
NODE_VERSION: 16.9.1
PROJ_VERSION: proj-9.1.1
DECIDIM_MODULE: decidim-homepage_interactive_map

jobs:
Expand Down Expand Up @@ -83,6 +84,18 @@ jobs:
key: npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
npm-
- uses: actions/cache@v2
id: proj-cache
with:
path: ./${{env.PROJ_VERSION}}
key: ${{env.PROJ_VERSION}}
- name: Install PROJ
run: |
./.github/install_proj.sh
- run: |
bundle config set build.rgeo-proj4 --with-proj-dir="/usr/local/bin/"
bundle pristine rgeo-proj4
name: Setup gem
- run: bundle exec rake test_app
name: Create test app
- run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots
Expand Down
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ gem "decidim-homepage_interactive_map", path: "."
gem "bootsnap", "~> 1.4"
gem "puma", "~> 5.5.1"

gem "rgeo", "~> 2.4"
gem "rgeo-proj4", "~> 3.1"

group :development, :test do
gem "byebug", "~> 11.0", platform: :mri

Expand Down
9 changes: 8 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ PATH
decidim-admin (>= 0.25.0, < 0.27)
decidim-core (>= 0.25.0, < 0.27)
decidim-dev (>= 0.25.0, < 0.27)
rgeo (~> 2.4)
rgeo-proj4 (~> 3.1)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -603,6 +605,9 @@ GEM
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.5)
rgeo (2.4.0)
rgeo-proj4 (3.1.1)
rgeo (~> 2.0)
rspec (3.11.0)
rspec-core (~> 3.11.0)
rspec-expectations (~> 3.11.0)
Expand Down Expand Up @@ -760,6 +765,8 @@ DEPENDENCIES
letter_opener_web (~> 1.3)
listen (~> 3.1)
puma (~> 5.5.1)
rgeo (~> 2.4)
rgeo-proj4 (~> 3.1)
rubocop-faker
spring (~> 2.0)
spring-watcher-listen (~> 2.0)
Expand All @@ -769,4 +776,4 @@ RUBY VERSION
ruby 2.7.1p83

BUNDLED WITH
2.3.10
2.3.14
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@ bundle exec rake db:migrate
bundle exec rake decidim_homepage_interactive_map:webpacker:install
```

* On OSX:
```bash
brew install proj
bundle config set build.rgeo-proj4 --with-proj-dir="/opt/homebrew/"
bundle pristine rgeo-proj4
bundle install
```

* On Ubuntu:
```bash
PROJ_VERSION=proj-9.1.1 ./.github/install_proj.sh
bundle config set build.rgeo-proj4 --with-proj-dir="/usr/local/bin/"
bundle pristine rgeo-proj4
bundle install
```

## How to use
### Existing positions
```
bundle exec rake decidim_homepage_interactive_map:repair_data
```

### New positions
No need to do anything, the module will automatically transpose the scope position.

In Decidim's backoffice, enable Interactive map content block.

## How it works
Expand All @@ -54,6 +79,7 @@ In Decidim's backoffice, enable Interactive map content block.
* If PP has location, places the marker at the defined address
* Otherwise, place the participatory process on the top right corner of assemblie marker (like a notification badge)


## Contributing

See [Decidim](https://github.com/decidim/decidim).
Expand Down
13 changes: 12 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

require "decidim/dev/common_rake"
require "rgeo"
require "rgeo/proj4"

def external_seeds
'load("../db/module_seeds.rb")'
Expand All @@ -14,6 +16,13 @@ def install_module(path)
end
end

def setup_dependencies(path)
Dir.chdir(path) do
raise "You must install Proj4 to use this module, please check https://github.com/rgeo/rgeo-proj4" if `which proj` == ""
raise "Proj4 was not setup properly please check README#install" unless RGeo::CoordSys::Proj4.supported?
end
end

def seed_db(path)
Dir.chdir(path) do
system("bundle exec rake db:seed")
Expand All @@ -23,11 +32,14 @@ end
desc "Generates a dummy app for testing"
task test_app: "decidim:generate_external_test_app" do
ENV["RAILS_ENV"] = "test"
setup_dependencies("spec/decidim_dummy_app")
install_module("spec/decidim_dummy_app")
end

desc "Generates a development app"
task :development_app do
setup_dependencies("development_app")

Bundler.with_original_env do
generate_decidim_app(
"development_app",
Expand All @@ -39,7 +51,6 @@ task :development_app do
"--demo"
)
end

install_module("development_app")
seed_db("development_app")
end
4 changes: 3 additions & 1 deletion app/commands/decidim/admin/create_scope.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "decidim/homepage_interactive_map/coordinates_swapper"

module Decidim
module Admin
# A command with all the business logic when creating a static scope.
Expand Down Expand Up @@ -38,7 +40,7 @@ def create_scope
name: form.name,
organization: form.organization,
code: form.code,
geojson: geojson,
geojson: Decidim::HomepageInteractiveMap::CoordinatesSwapper.convert_geojson(geojson),
scope_type: form.scope_type,
parent: @parent_scope
},
Expand Down
4 changes: 3 additions & 1 deletion app/commands/decidim/admin/update_scope.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require "decidim/homepage_interactive_map/coordinates_swapper"

module Decidim
module Admin
# A command with all the business logic when updating a scope.
Expand Down Expand Up @@ -46,7 +48,7 @@ def attributes
{
name: form.name,
code: form.code,
geojson: geojson,
geojson: Decidim::HomepageInteractiveMap::CoordinatesSwapper.convert_geojson(geojson),
scope_type: form.scope_type
}
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,6 @@ def interactive_map_for(geojson, css_class = "row column")
content_tag(:div, "", map_html_options) + content
end
end

def interactive_map_script(content_blocks)
if content_blocks.map(&:manifest_name).include?("interactive_map") && content_blocks.map(&:manifest_name).include?("upcoming_meetings")
"decidim/homepage_interactive_map/interactive_map_without_dependencies"
elsif content_blocks.map(&:manifest_name).include?("interactive_map")
"decidim/homepage_interactive_map/interactive_map"
else
""
end
end
end
end
end
Expand Down
5 changes: 0 additions & 5 deletions app/packs/entrypoints/decidim_homepage_interactive_map.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
import "proj4leaflet"
import "leaflet"
import "leaflet-tilelayer-here"
import "leaflet-svgicon"
import "leaflet.markercluster"
import "src/decidim/homepage_interactive_map/interactive_map"
import "src/decidim/homepage_interactive_map/scope"
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
import "src/vendor/leaflet-polylabel-centroid";
import * as L from "leaflet";
import proj4 from "proj4"
import "src/decidim/vendor/leaflet-tilelayer-here"
import "src/decidim/map/icon.js" // comes with Decidim
import "leaflet.markercluster"; // Comes with Decidim
import "leaflet.featuregroup.subgroup" // included in this package.json
import "src/vendor/jquery.truncate"

L.DivIcon.SVGIcon.DecidimIcon = L.DivIcon.SVGIcon.extend({
options: {
Expand Down Expand Up @@ -43,9 +36,6 @@ L.DivIcon.SVGIcon.DecidimIcon = L.DivIcon.SVGIcon.extend({

const map = L.map('interactive_map', {scrollWheelZoom: false});

// Add Proj4 configurations
proj4.defs("EPSG:3943", "+proj=lcc +lat_1=42.25 +lat_2=43.75 +lat_0=43 +lon_0=3 +x_0=1700000 +y_0=2200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");

let zoomOrigin = map.getZoom();
let allZonesLayer = L.featureGroup();
let allZonesMarkers = [];
Expand Down Expand Up @@ -170,7 +160,7 @@ L.DivIcon.SVGIcon.DecidimIcon = L.DivIcon.SVGIcon.extend({
});

// Convert data from GeoJSON
const geoJsonLayer = L.Proj.geoJson(geoJson, {
const geoJsonLayer = L.geoJson(geoJson, {
style: (feature) => {
return {
interactive: false,
Expand Down
189 changes: 175 additions & 14 deletions db/module_seeds.rb

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions decidim-homepage_interactive_map.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ Gem::Specification.new do |s|
s.add_dependency "decidim-admin", Decidim::HomepageInteractiveMap::COMPAT_DECIDIM_VERSION
s.add_dependency "decidim-core", Decidim::HomepageInteractiveMap::COMPAT_DECIDIM_VERSION
s.add_dependency "decidim-dev", Decidim::HomepageInteractiveMap::COMPAT_DECIDIM_VERSION
s.add_dependency "rgeo", "~> 2.4"
s.add_dependency "rgeo-proj4", "~> 3.1"
end
60 changes: 60 additions & 0 deletions lib/decidim/homepage_interactive_map/coordinates_swapper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# frozen_string_literal: true

require "rgeo"
require "rgeo/proj4"

module Decidim
module HomepageInteractiveMap
# This class swaps the coordinates of a feature
module CoordinatesSwapper
def self.convert_geojson(geojson, opts = {})
return nil if geojson.nil?

from = opts[:from] || detect_crs(geojson) || "EPSG:3857"
to = opts[:to] || "EPSG:4326"

geojson_clone = geojson.dup.deep_symbolize_keys
new_coordinates = transform(geojson_clone[:parsed_geometry][:geometry][:coordinates], from, to)
new_geometry = geojson_clone[:parsed_geometry][:geometry].merge(
{
coordinates: new_coordinates,
crs: to
}
)
new_parsed_geometry = geojson_clone[:parsed_geometry].merge(geometry: new_geometry)

geojson_clone.merge(parsed_geometry: new_parsed_geometry)
end

def self.transform(coordinates, from, to)
return coordinates if from == to

coord_sys_from = coord_sys(from)
coord_sys_to = coord_sys(to)

return transform_coords(coord_sys_from, coord_sys_to, coordinates.first, coordinates.last, nil) if coordinates.length == 2

coordinates.map do |coord|
if coord.first.is_a?(Array)
transform(coord, from, to)
else
lat, lon = coord
transform_coords(coord_sys_from, coord_sys_to, lat, lon, nil)
end
end
end

def self.transform_coords(projection, geography, lat, lon, alt)
RGeo::CoordSys::Proj4.transform_coords(projection, geography, lat, lon, alt)
end

def self.coord_sys(coord_sys)
RGeo::CoordSys::Proj4.create(coord_sys)
end

def self.detect_crs(geojson)
geojson.dup.deep_symbolize_keys.dig(:parsed_geometry, :geometry, :crs)
end
end
end
end
12 changes: 12 additions & 0 deletions lib/tasks/interactive_map.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

require "decidim/homepage_interactive_map/coordinates_swapper"

namespace :decidim_homepage_interactive_map do
desc "Repair the interactive map data to ensure the geojson has a EPSG:3857 format"
task repair_data: :environment do
Decidim::Scope.where.not(geojson: nil).find_each do |scope|
scope.update!(geojson: Decidim::HomepageInteractiveMap::CoordinatesSwapper.convert_geojson(scope.geojson))
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -71,35 +71,6 @@ module HomepageInteractiveMap
end
end
end

describe "#interactive_map_script" do
subject { helper.interactive_map_script(content_blocks) }

let(:content_blocks) { Decidim::ContentBlock.published.for_scope(:homepage, organization: organization) }

before do
create :content_block, organization: organization, scope_name: :homepage, manifest_name: :hero
create :content_block, organization: organization, scope_name: :homepage, manifest_name: :last_activity
end

it { is_expected.to be_empty }

context "when interactive_map content block is defined" do
before do
create :content_block, organization: organization, scope_name: :homepage, manifest_name: :interactive_map
end

it { is_expected.to eq("decidim/homepage_interactive_map/interactive_map") }

context "and upcoming_meetings content block is also defined" do
before do
create :content_block, organization: organization, scope_name: :homepage, manifest_name: :upcoming_meetings
end

it { is_expected.to eq("decidim/homepage_interactive_map/interactive_map_without_dependencies") }
end
end
end
end
end
end
Loading

0 comments on commit 0e80a82

Please sign in to comment.