Use Cases

Claude Code के साथ Google Maps Web

Claude Code का उपयोग करके google maps web सीखें। Practical tips और code examples शामिल हैं।

地図featuresको Claude Code सेintegrationする

店舗search、配達追跡、不動産search आदि、地図featuresをज़रूरीとするapplicationは数多くあり है।Claude Code का उपयोग करके、Google Maps APIやMapboxのintegration、マーカーdisplay、ジオコーディングをefficientlyimplementationでき है।

Google Maps Reactcomponent

> Google Maps APIをReactアプリにintegrationして。
> 複数マーカーdisplay、情報ウィンドウ、現在地fetch、
> 住所search(ジオコーディング)をimplement करो。
// src/components/GoogleMap.tsx
'use client';
import { useRef, useEffect, useState, useCallback } from 'react';
import { Loader } from '@googlemaps/js-api-loader';

interface MapMarker {
  id: string;
  position: { lat: number; lng: number };
  title: string;
  description?: string;
}

interface Props {
  markers: MapMarker[];
  center?: { lat: number; lng: number };
  zoom?: number;
  onMarkerClick?: (marker: MapMarker) => void;
}

export function GoogleMap({
  markers,
  center = { lat: 35.6812, lng: 139.7671 }, // 東京駅
  zoom = 13,
  onMarkerClick,
}: Props) {
  const mapRef = useRef<HTMLDivElement>(null);
  const [map, setMap] = useState<google.maps.Map | null>(null);
  const [infoWindow, setInfoWindow] = useState<google.maps.InfoWindow | null>(null);

  useEffect(() => {
    const loader = new Loader({
      apiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY!,
      version: 'weekly',
      libraries: ['places'],
    });

    loader.load().then(() => {
      if (!mapRef.current) return;
      const mapInstance = new google.maps.Map(mapRef.current, {
        center,
        zoom,
        styles: [
          { featureType: 'poi', stylers: [{ visibility: 'simplified' }] },
        ],
      });
      setMap(mapInstance);
      setInfoWindow(new google.maps.InfoWindow());
    });
  }, []);

  useEffect(() => {
    if (!map || !infoWindow) return;

    markers.forEach((markerData) => {
      const marker = new google.maps.Marker({
        position: markerData.position,
        map,
        title: markerData.title,
        animation: google.maps.Animation.DROP,
      });

      marker.addListener('click', () => {
        infoWindow.setContent(`
          <div style="padding:8px">
            <h3 style="font-weight:bold;margin-bottom:4px">${markerData.title}</h3>
            ${markerData.description ? `<p style="color:#666">${markerData.description}</p>` : ''}
          </div>
        `);
        infoWindow.open(map, marker);
        onMarkerClick?.(markerData);
      });
    });
  }, [map, markers, infoWindow, onMarkerClick]);

  return <div ref={mapRef} className="w-full h-96 rounded-xl" />;
}

住所search(ジオコーディング)

// src/lib/geocoding.ts
export async function geocodeAddress(address: string) {
  const geocoder = new google.maps.Geocoder();

  const result = await geocoder.geocode({ address });

  if (result.results.length === 0) {
    throw new Error('住所が見つかりませんでした');
  }

  const location = result.results[0].geometry.location;
  return {
    lat: location.lat(),
    lng: location.lng(),
    formattedAddress: result.results[0].formatted_address,
  };
}

export async function reverseGeocode(lat: number, lng: number) {
  const geocoder = new google.maps.Geocoder();
  const result = await geocoder.geocode({
    location: { lat, lng },
  });

  return result.results[0]?.formatted_address || '住所不明';
}

店舗searchcomponent

// src/components/StoreLocator.tsx
'use client';
import { useState } from 'react';
import { GoogleMap } from './GoogleMap';
import { geocodeAddress } from '@/lib/geocoding';

interface Store {
  id: string;
  name: string;
  address: string;
  position: { lat: number; lng: number };
  phone: string;
  hours: string;
}

export function StoreLocator({ stores }: { stores: Store[] }) {
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedStore, setSelectedStore] = useState<Store | null>(null);
  const [mapCenter, setMapCenter] = useState({ lat: 35.6812, lng: 139.7671 });

  const handleSearch = async () => {
    try {
      const result = await geocodeAddress(searchQuery);
      setMapCenter({ lat: result.lat, lng: result.lng });
    } catch {
      alert('住所が見つかりませんでした');
    }
  };

  const markers = stores.map((store) => ({
    id: store.id,
    position: store.position,
    title: store.name,
    description: store.address,
  }));

  return (
    <div className="grid md:grid-cols-3 gap-6">
      <div className="md:col-span-1 space-y-4">
        <div className="flex gap-2">
          <input
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder="住所・地名でsearch"
            className="flex-1 border rounded-lg px-3 py-2"
            onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
          />
          <button onClick={handleSearch} className="bg-blue-600 text-white px-4 rounded-lg">
            search
          </button>
        </div>

        <div className="space-y-2 max-h-96 overflow-y-auto">
          {stores.map((store) => (
            <div
              key={store.id}
              onClick={() => {
                setSelectedStore(store);
                setMapCenter(store.position);
              }}
              className={`p-3 rounded-lg cursor-pointer border ${
                selectedStore?.id === store.id ? 'border-blue-500 bg-blue-50' : 'hover:bg-gray-50'
              }`}
            >
              <h4 className="font-medium">{store.name}</h4>
              <p className="text-sm text-gray-500">{store.address}</p>
              <p className="text-sm text-gray-400">{store.hours}</p>
            </div>
          ))}
        </div>
      </div>

      <div className="md:col-span-2">
        <GoogleMap
          markers={markers}
          center={mapCenter}
          zoom={14}
          onMarkerClick={(m) => setSelectedStore(stores.find((s) => s.id === m.id) || null)}
        />
      </div>
    </div>
  );
}

現在地のfetch

// src/hooks/useGeolocation.ts
import { useState, useEffect } from 'react';

export function useGeolocation() {
  const [position, setPosition] = useState<{ lat: number; lng: number } | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    if (!navigator.geolocation) {
      setError('इसブラウザでは位置情報が利用できません');
      return;
    }

    navigator.geolocation.getCurrentPosition(
      (pos) => setPosition({ lat: pos.coords.latitude, lng: pos.coords.longitude }),
      (err) => setError(err.message),
      { enableHighAccuracy: true, timeout: 10000 }
    );
  }, []);

  return { position, error };
}

関連記事

data可視化とのintegrationはdata可視化のimplementation、APIkeyのmanagementはsecurity監査भी reference के लिए देखें。

Google Maps Platform のofficial documentation(developers.google.com/maps)で最新のAPIリファレンス confirmでき है।

#Claude Code #Google Maps #map #Mapbox #geolocation