feat: add map feature to city show page
- Implement MapController for displaying city maps - Add map rendering in the city show view - Include weather arts in the city show controller - Update asset pipeline to include Leaflet CSS and JS This commit introduces a map feature that allows users to view geographical information related to cities. The map is integrated with weather arts data, enhancing the overall functionality of the city show page.
This commit is contained in:
parent
95f94cb73b
commit
df456d1031
@ -1,4 +1,5 @@
|
||||
@import "photoswipe/dist/photoswipe.css";
|
||||
/*@import "leaflet/dist/leaflet.css";*/
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
|
@ -35,6 +35,7 @@ class CitiesController < ApplicationController
|
||||
|
||||
def show
|
||||
@city = City.friendly.find(params[:id])
|
||||
@arts = @city.weather_arts.order(weather_date: :desc).includes([ :image_attachment ])
|
||||
ahoy.track "View City", {
|
||||
city_id: @city.id,
|
||||
name: @city.name,
|
||||
|
@ -8,9 +8,12 @@ import PhotoSwipeLightBoxController from "./photo_swipe_lightbox_controller"
|
||||
import FlashMessageController from "./flash_controller"
|
||||
import SearchController from "./search_controller"
|
||||
import PageLoadTimeController from "./page_load_time_controller"
|
||||
import MapController from "./map_controller"
|
||||
|
||||
application.register("hello", HelloController)
|
||||
application.register("photo-swipe-lightbox", PhotoSwipeLightBoxController)
|
||||
application.register("flash", FlashMessageController)
|
||||
application.register("search", SearchController)
|
||||
application.register("page-load-time", PageLoadTimeController)
|
||||
application.register("map", MapController)
|
||||
|
||||
|
58
app/javascript/controllers/map_controller.js
Normal file
58
app/javascript/controllers/map_controller.js
Normal file
@ -0,0 +1,58 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
import L from 'leaflet'
|
||||
|
||||
import 'leaflet/dist/leaflet.css'
|
||||
import iconUrl from 'leaflet/dist/images/marker-icon.png';
|
||||
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
|
||||
// import iconRetinaUrl from '../images/leaflet/marker-icon-2x.png';
|
||||
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
|
||||
|
||||
export default class extends Controller {
|
||||
static values = {
|
||||
latitude: Number,
|
||||
longitude: Number
|
||||
}
|
||||
|
||||
init() {
|
||||
}
|
||||
|
||||
connect() {
|
||||
|
||||
delete L.Icon.Default.prototype._getIconUrl
|
||||
L.Icon.Default.mergeOptions({
|
||||
// iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
|
||||
// iconUrl: require('leaflet/dist/images/marker-icon.png'),
|
||||
// shadowUrl: require('leaflet/dist/images/marker-shadow.png')
|
||||
iconRetinaUrl: iconRetinaUrl,
|
||||
iconUrl: iconUrl,
|
||||
shadowUrl: shadowUrl,
|
||||
});
|
||||
|
||||
this.initializeMap()
|
||||
}
|
||||
|
||||
initializeMap() {
|
||||
// 创建地图实例
|
||||
this.map = L.map(this.element).setView(
|
||||
[this.latitudeValue, this.longitudeValue],
|
||||
4 // 缩放级别
|
||||
)
|
||||
|
||||
// 添加地图图层
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© OpenStreetMap contributors'
|
||||
}).addTo(this.map)
|
||||
|
||||
// 添加标记
|
||||
L.marker([this.latitudeValue, this.longitudeValue])
|
||||
.addTo(this.map)
|
||||
.bindPopup(document.querySelector('h1').textContent)
|
||||
.openPopup()
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.map) {
|
||||
this.map.remove()
|
||||
}
|
||||
}
|
||||
}
|
8
app/views/cities/_map.html.erb
Normal file
8
app/views/cities/_map.html.erb
Normal file
@ -0,0 +1,8 @@
|
||||
<div class="mt-8">
|
||||
<div
|
||||
data-controller="map"
|
||||
data-map-latitude-value="<%= city.latitude %>"
|
||||
data-map-longitude-value="<%= city.longitude %>"
|
||||
class="w-full h-[400px] rounded-lg shadow-lg">
|
||||
</div>
|
||||
</div>
|
@ -61,6 +61,8 @@
|
||||
], as: :stat %>
|
||||
</div>
|
||||
|
||||
<%= render 'cities/map', city: @city %>
|
||||
|
||||
<%= render 'cities/admin_panel' %>
|
||||
</div>
|
||||
</div>
|
||||
@ -86,7 +88,7 @@
|
||||
|
||||
<!-- 天气艺术卡片网格 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
<%= render partial: 'weather_arts/card', collection: @city.weather_arts.order(weather_date: :desc), as: :weather_art %>
|
||||
<%= render partial: 'weather_arts/card', collection: @arts, as: :weather_art %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -79,4 +79,6 @@ Rails.application.configure do
|
||||
|
||||
# Apply autocorrection by RuboCop to files generated by `bin/rails generate`.
|
||||
# config.generators.apply_rubocop_autocorrect_after_generate!
|
||||
|
||||
config.serve_static_assets = true
|
||||
end
|
||||
|
@ -5,3 +5,9 @@ Rails.application.config.assets.version = "1.0"
|
||||
|
||||
# Add additional assets to the asset load path.
|
||||
# Rails.application.config.assets.paths << Emoji.images_path
|
||||
# Rails.application.config.assets.paths << Rails.root.join("app/assets/builds")
|
||||
# Rails.application.config.assets.paths << Rails.root.join("node_modules")
|
||||
# Rails.application.config.assets.precompile += %w( *.png *.jpg *.jpeg *.gif )
|
||||
# Rails.application.config.assets.paths << Rails.root.join("app/assets/builds")
|
||||
# Rails.application.config.assets.precompile += %w( *.png *.jpg *.jpeg *.gif )
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
"esbuild": "^0.24.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets --loader:.woff=file --loader:.woff2=file --loader:.ttf=file --loader:.eot=file --asset-names=[name]-[hash]",
|
||||
"build": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets --loader:.woff=file --loader:.woff2=file --loader:.ttf=file --loader:.eot=file --loader:.png=file --asset-names=[name]-[hash].digested --chunk-names=[name]-[hash].digested",
|
||||
"build:css": "tailwindcss -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css && sass ./app/assets/stylesheets/active_admin.scss:./app/assets/builds/active_admin.css --no-source-map --load-path=node_modules"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -18,6 +18,7 @@
|
||||
"autoprefixer": "^10.4.20",
|
||||
"jquery": "^3.7.1",
|
||||
"jquery-ui": "^1.14.1",
|
||||
"leaflet": "^1.9.4",
|
||||
"photoswipe": "^5.4.4",
|
||||
"postcss": "^8.5.1",
|
||||
"sass": "^1.83.4",
|
||||
|
@ -739,6 +739,11 @@ jquery-ujs@^1.2.2:
|
||||
resolved "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz"
|
||||
integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==
|
||||
|
||||
leaflet@^1.9.4:
|
||||
version "1.9.4"
|
||||
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.4.tgz#23fae724e282fa25745aff82ca4d394748db7d8d"
|
||||
integrity sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==
|
||||
|
||||
lilconfig@^3.0.0, lilconfig@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz"
|
||||
|
Loading…
Reference in New Issue
Block a user