| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- import axios from 'axios';
- const GEOCODING_URL = 'https://maps.googleapis.com/maps/api/geocode/json';
- const parseAddressComponents = (components) => {
- const get = (type, nameType = 'long_name') =>
- components.find((c) => c.types.includes(type))?.[nameType] ?? '';
- return {
- address: `${get('route')}`.trim(),
- number: get('street_number'),
- district: get('sublocality_level_1') || get('sublocality') || get('neighborhood'),
- city: get('administrative_area_level_2'),
- state: get('administrative_area_level_1', 'short_name'),
- zip_code: get('postal_code').replace(/\D/g, ''),
- };
- };
- const geocodeViaGoogleMaps = async (request) => {
- const geocoder = new window.google.maps.Geocoder();
- const { results } = await geocoder.geocode(request);
- return results ?? [];
- };
- export const useGeocodingApi = () => {
- const geocodeCep = async (cep) => {
- const cleaned = cep.replace(/\D/g, '');
- const apiKey = process.env.GOOGLE_MAPS_API_KEY;
- const usandoGeocoderNativo = !!window.google?.maps?.Geocoder;
- if (usandoGeocoderNativo) {
- const results = await geocodeViaGoogleMaps({ address: `${cleaned}, Brazil` });
- if (!results.length) return null;
- const result = results[0];
- const parsed = parseAddressComponents(result.address_components);
- return {
- lat: result.geometry.location.lat(),
- lng: result.geometry.location.lng(),
- ...parsed,
- };
- }
- const { data } = await axios.get(GEOCODING_URL, {
- params: { address: `${cleaned}, Brazil`, key: apiKey },
- });
- if (data.status !== 'OK' || !data.results.length) return null;
- const result = data.results[0];
- const { lat, lng } = result.geometry.location;
- return { lat, lng, ...parseAddressComponents(result.address_components) };
- };
- const reverseGeocode = async (lat, lng) => {
- const apiKey = process.env.GOOGLE_MAPS_API_KEY;
- const usandoGeocoderNativo = !!window.google?.maps?.Geocoder;
- if (usandoGeocoderNativo) {
- const results = await geocodeViaGoogleMaps({ location: { lat, lng } });
- if (!results.length) return null;
- return { lat, lng, ...parseAddressComponents(results[0].address_components) };
- }
- const { data } = await axios.get(GEOCODING_URL, {
- params: { latlng: `${lat},${lng}`, key: apiKey },
- });
- if (data.status !== 'OK' || !data.results.length) return null;
- const result = data.results[0];
- return { lat, lng, ...parseAddressComponents(result.address_components) };
- };
- const geocodeFullAddress = async ({ address, number, district, zip_code, city, state }) => {
- const parts = [address, number, district, zip_code, city, state, 'Brazil'].filter(Boolean);
- const query = parts.join(', ');
- const apiKey = process.env.GOOGLE_MAPS_API_KEY;
- const usandoGeocoderNativo = !!window.google?.maps?.Geocoder;
- if (usandoGeocoderNativo) {
- const results = await geocodeViaGoogleMaps({ address: query });
- if (!results.length) return null;
- const result = results[0];
- return {
- lat: result.geometry.location.lat(),
- lng: result.geometry.location.lng(),
- ...parseAddressComponents(result.address_components),
- };
- }
- const { data } = await axios.get(GEOCODING_URL, {
- params: { address: query, key: apiKey },
- });
- if (data.status !== 'OK' || !data.results.length) return null;
- const result = data.results[0];
- const { lat, lng } = result.geometry.location;
- return { lat, lng, ...parseAddressComponents(result.address_components) };
- };
- return { geocodeCep, reverseGeocode, geocodeFullAddress };
- };
|