Skip to content

Commit

Permalink
フォーカス時に詳細画面が出るように機能を追加 #53
Browse files Browse the repository at this point in the history
  • Loading branch information
minagishl committed Jan 27, 2024
1 parent f952a45 commit 027f1ef
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 44 deletions.
15 changes: 15 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ postgres-data

# temporary file
tmp
.tw-patch/
/.tw-patch/
4 changes: 4 additions & 0 deletions .tw-patch/tw-class-list.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"flex",
"flex-1",
"flex-col",
"flex-row",
"font-light",
"font-medium",
"font-normal",
Expand All @@ -50,6 +51,7 @@
"hover:bg-zinc-900",
"items-center",
"items-end",
"justify-between",
"justify-center",
"left-1/2",
"list-none",
Expand Down Expand Up @@ -80,6 +82,7 @@
"pt-3",
"pt-5",
"px-1",
"px-2",
"px-3",
"px-4",
"py-1",
Expand All @@ -104,6 +107,7 @@
"sm:w-4/12",
"sm:w-fit",
"space-x-1",
"space-y-5",
"text-base",
"text-center",
"text-lg",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.11.5",
"@types/node": "^20.11.7",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.4.17",
Expand Down
16 changes: 8 additions & 8 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions src/app/page.tsx → src/app/[[...map]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useSearchParams } from 'next/navigation';
import { useSearchParams, useRouter } from 'next/navigation';
import { Map, GeolocateControl, NavigationControl, LngLatBounds } from 'react-map-gl/maplibre';
import 'maplibre-gl/dist/maplibre-gl.css';

Expand All @@ -20,7 +20,11 @@ import DevelopmentMenu from '@/components/DevelopmentMenu';
// @ts-ignore
import * as turf from '@turf/turf';

const Page = () => {
export default function Page({ params }: { params: { map?: string } }) {
// 建物の種類を指定しているが、IDが指定されていない場合にリダイレクトさせる
const router = useRouter();
if (params.map?.[0] && !params.map?.[1]) router.push('/');

const searchParams = useSearchParams();
const searchParamsString = searchParams.toString();
const printMode = searchParamsString === 'print=true';
Expand Down Expand Up @@ -172,6 +176,7 @@ const Page = () => {
geojson={geoJsonWithStyle.geojson}
style={geoJsonWithStyle.style}
printMode={mapPrintMode}
isProduction={isProduction}
/>
);
})}
Expand Down Expand Up @@ -208,6 +213,4 @@ const Page = () => {
</div>
</div>
);
};

export default Page;
}
2 changes: 1 addition & 1 deletion src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const runtime = "edge";
export const runtime = 'edge';
import NextAuth from 'next-auth';
import { options } from '@/app/options';

Expand Down
37 changes: 32 additions & 5 deletions src/components/GeoJsonFeatureList.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import PositionType from './PositionType';
import Icon from './Icon';

import Accordion from '@mui/material/Accordion';
import AccordionSummary from '@mui/material/AccordionSummary';
import AccordionDetails from '@mui/material/AccordionDetails';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import Grid from '@mui/material/Grid';
import ProvideInformationButton from './ProvideInformationButton';
import ProvideInformationDrawer, { type Content } from './ProvideInformationDrawer';
import { useState } from 'react';
import { Feature, Geometry, GeoJsonProperties, Point } from 'geojson';
import { useState, useEffect } from 'react';
import { usePathname } from 'next/navigation';

interface GeoJsonFeatureListProps {
emoji?: string;
feature: any | undefined;
feature: Feature<Geometry, GeoJsonProperties> | undefined;
index: number;
geoIndex: number;
length: number;
Expand All @@ -26,16 +27,31 @@ export default function GeoJsonFeatureList({
length,
}: GeoJsonFeatureListProps): React.JSX.Element {
const [menuState, setMenuState] = useState<boolean>(false);
const [expanded, setExpanded] = useState<boolean>(false);
const pathname = usePathname();

useEffect(() => {
const url = `${pathname}`;
const parts = url.split('/').filter(Boolean);
const amenity = parts[0];
const id = parts[1];
if (!feature?.properties?.amenity) return;
if (feature.properties?.amenity === amenity && String(feature.id).includes(id)) {
setExpanded(true);
}
}, [feature, pathname]);

if (!emoji || !feature) return <p>Object is Null</p>;

const name = feature.properties?.name;
const address: string = feature.properties?.['KSJ2:AdminArea'] + ' ' + feature.properties?.['KSJ2:ADS'];
const buildingIdString = String(feature.id);
const buildingId = buildingIdString.substring(buildingIdString.lastIndexOf('/') + 1);

// 情報提供フォームのオプション
const option: Content = {
shelterName: name,
shelterId: feature.id,
shelterId: String(feature.id),
};

const toggleDrawer = (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
Expand All @@ -49,6 +65,17 @@ export default function GeoJsonFeatureList({
setMenuState(open);
};

const handle = () => {
setExpanded(!expanded);
if (feature.properties?.amenity) {
window.history.pushState(
null,
'',
'/' + feature.properties.amenity + '/' + buildingId + window.location.hash
);
}
};

return (
<div key={name} className={`py-2 ${length !== index + 1 && 'border-b border-zinc-200'}`}>
<ProvideInformationDrawer
Expand All @@ -58,7 +85,7 @@ export default function GeoJsonFeatureList({
options={option}
/>
<PositionType emoji={emoji} index={index} geoIndex={geoIndex} />
<Accordion sx={{ boxShadow: 0 }}>
<Accordion sx={{ boxShadow: 0 }} onClick={handle} expanded={expanded}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Grid item xs={3}>
<Icon emoji={emoji} iconColor="white" />
Expand Down
74 changes: 53 additions & 21 deletions src/components/GeoJsonToSomethings.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
// @ts-ignore
import * as turf from '@turf/turf';

import { Feature, FeatureCollection, GeoJsonProperties, Point } from 'geojson';
import { Fragment, useCallback, useEffect, useState } from 'react';
import { Fragment, useCallback, useEffect } from 'react';
import { Layer, Source, useMap } from 'react-map-gl/maplibre';
import { usePathname } from 'next/navigation';
import Pointer from './Pointer';
import Icon from './Icon';

function calculateCenterFromGeometry(feature: any) {
switch (feature.geometry.type) {
case 'Polygon':
const polygonFeatures = turf.polygon(feature.geometry.coordinates);
return turf.centroid(polygonFeatures);
case 'MultiPolygon':
const multiPolygonFeatures = turf.multiPolygon(feature.geometry.coordinates);
return turf.centroid(multiPolygonFeatures);
case 'LineString':
const bbox = turf.bbox(feature);
const polygon = turf.bboxPolygon(bbox);
return turf.centroid(polygon);
case 'Point':
return turf.point(feature.geometry.coordinates);
default:
return undefined;
}
}

export const GeoJsonToSomethings: React.FC<{
geojson?: FeatureCollection;
emoji?: string;
Expand All @@ -15,7 +36,8 @@ export const GeoJsonToSomethings: React.FC<{
emoji?: string;
};
printMode?: boolean;
}> = ({ geojson, emoji, style, printMode }) => {
isProduction?: boolean;
}> = ({ geojson, style, printMode, isProduction }) => {
const { current: map } = useMap();

const onClickMarker = useCallback(
Expand All @@ -32,6 +54,33 @@ export const GeoJsonToSomethings: React.FC<{
[map]
);

// URL変更時に実行される処理
const pathname = usePathname();

useEffect((): void => {
const url = `${pathname}`;
const parts = url.split('/').filter(Boolean);
const amenity = parts[0];
const id = parts[1];

// デバッグ用
if (!isProduction) {
console.log({ amenity, id, path: url }); // Output Example: {"school", "0123456789", "/school/0123456789"}
console.log('The path has been updated: ' + url); // 開発環境時のみ実行
}

if (!geojson?.features) return;
for (const feature of geojson?.features) {
if (feature.properties?.amenity === amenity && String(feature.id).includes(id)) {
let center: Feature<Point, GeoJsonProperties> | undefined = undefined;
center = calculateCenterFromGeometry(feature);
onClickMarker(center);
return;
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname]);

if (geojson === undefined || geojson.features === undefined) {
return null;
}
Expand Down Expand Up @@ -72,25 +121,7 @@ export const GeoJsonToSomethings: React.FC<{
}

let center: Feature<Point, GeoJsonProperties> | undefined = undefined;
switch (feature.geometry.type) {
case 'Polygon':
const polygonFeatures = turf.polygon(feature.geometry.coordinates);
center = turf.centroid(polygonFeatures);
break;
case 'MultiPolygon':
const multiPolygonFeatures = turf.multiPolygon(feature.geometry.coordinates);
center = turf.centroid(multiPolygonFeatures);
break;
case 'LineString':
const bbox = turf.bbox(feature);
const polygon = turf.bboxPolygon(bbox);
center = turf.centroid(polygon);
break;
case 'Point':
center = turf.point(feature.geometry.coordinates);
default:
break;
}
center = calculateCenterFromGeometry(feature);
if (center === undefined) {
return null;
}
Expand Down Expand Up @@ -156,6 +187,7 @@ export const GeoJsonToSomethings: React.FC<{
style={style}
index={index}
printMode={printMode}
isProduction={isProduction}
>
{printMode ? (
index + 1
Expand Down
Loading

0 comments on commit 027f1ef

Please sign in to comment.