머리말
오늘날 모바일 인터넷의 광범위한 개발로 앱 개발은 많은 회사가 모바일 인터넷에 입국하는 첫 번째 선택이되었습니다. 저자는 많은 앱을 개발했으며 많은 앱이 그러한 기능, 즉 인근 사람들을 얻기위한 기능을 가지고 있음을 발견했습니다. 근처 사람들을 얻는 방법? 사실, 그것은 매우 간단합니다. 사용자의 좌표 (위도 및 경도) 정보를 항상 데이터베이스에 기록한 다음 데이터베이스의 모든 사용자와 현재 사용자의 좌표를 기반으로 특정 범위 내의 현재 좌표 위치를 검색하는 것입니다.
실제로, 지리적 위치가 변하지 않는 두 피험자 사이의 거리의 경우 결과를 직접 정적으로 정적하는 것이 가장 좋습니다. 즉, 구성에 직접 작성하십시오.
예를 들어, 집 근처의 지하철 역을 찾으십시오.
이 경우, 일반적으로 "집"의 주제는 쉽게 "돌아 다니지"않습니다. 쿼리마다 한 번 거리를 계산하는 것은 의미가 없습니다. 거리를 유지하고 직접 쿼리하는 것이 가장 좋습니다.
다른 사례 :
앱 사용자의 위치 근처에 지하철 역을 가져옵니다.
이 경우 사용자의 지리적 위치가 변경됩니다. 따라서 실제 거리는 매번 실시간으로 계산해야합니다.
구현 아이디어
지구를 표준 구로 취급하고 구형 거리 공식을 사용하여 구형 표면의 두 지점 사이의 큰 원의 아크 길이를 계산하십시오.
구형 거리
public static double getDistance2 (Double Long1, Double Lat1, Double Long2, Double Lat2) {lat1 = rad (lat1); lat2 = rad (lat2); 이중 A = lat1 -lat2; 이중 B = rad (long1 -long2); Double SA2 = Math.Sin (A / 2.0); Double SB2 = Math.Sin (B / 2.0); 반환 2 * earth_mean_radius_km * math.asin (math.sqrt (sa2 * sa2 + math.cos (lat1) * math.cos (lat2) * sb2 * sb2);}두 지점 사이의 위도와 경도를 알고 있습니다.
물론이 계산은 데이터베이스에 배치 한 다음 거리에 따라 다시 정렬해야합니다. 위의 공식을 SQL로 가져 오십시오.
근처 지하철역의 예
지하철역 건설을위한 예제
테이블 스테이션 생성 (id int auto_increment 기본 키, 이름 varchar (20) null 댓글 'MRT 스테이션 이름', lng 더블 널 댓글 'longitude', lat double null comment 'Dimension');
SQL 예제
@TARGETLAT = 31.175702; SET @TARGETLNG = 121.519095; SELECT S.ID, S.NAME, S.LNG, S.LAT (6378.138 * 2 * ASIN) @targetlat * pi () / 180) * cos (s.lat * pi () / 180) * pow (sin ((@targetlng * pi () / 180 -s.lng * pi () / 180) / 2), 2))) * 1000) 거리 ASC, S.idlimit 20;
그중에서도 TargetLat과 TargetLng는 사용자의 지리적 위치입니다.
이것은 실제로 목표를 달성 할 수 있습니다. 그러나 이것은 모든 데이터와 사용자 사이의 거리를 먼저 계산 한 다음 정렬하는 것입니다.
지하철역의 수가 너무 커지면이 작업은 덜 우아합니다. 우아 할뿐만 아니라 매우 효율적입니다.
최적화
실제로 거리를 계산하기 전에 많은 데이터를 필터링 할 수 있습니다.
상하이 지하철역 사이의 거리를 계산할 때 미국 지하철역 사이의 거리를 계산할 필요는 없습니다.
대부분의 응용 프로그램에서 원치 않는 데이터를 먼저 필터링 할 수 있습니다.
예를 들어, 데이터가 도시를 구별 할 때 SQL을 다음과 같이 변경할 수 있습니다.
@targetlat = 31.175702; set @targetlng = 121.519095; set @cityId = 605; sect S.id, s.name, s.lng, s.lat, round (6378.138 * 2 * asin (sqrt (pow (sin (@targetlat * pi) / 180 -),) 2) + cos (@targetlat * pi () / 180) * cos (s.lat * pi () / 180) * pow (sin ((@targetlng * pi () / 180 -s.lng * pi () / 180) / 2), 2)))))))))))))))))))) s.idlimit 20;
위의 개선은 계산하기 전에 계산할 대부분의 데이터를 제거하는 것입니다. Changsha 지하철역을 찾을 때 상하이에서 먼저 검색 할 필요가 없습니다.
물론,이 상황은 사용자가 미리 위치한 도시를 알 수 있기 때문에 약간 특별합니다.
또 다른 개선은 다음과 같습니다.
사용자의 위치를 중심으로 사용하면 반경 R이있는 원을 그린 다음 원의 외부 사변형의 위도와 경도 범위를 반대로 배출하십시오. 거리를 계산하기 전에 외부 사변형의 경도와 경도 밖에서 데이터를 필터링하십시오.
이상적인 반경 R을 지정하고 기준을 먼저 충족 할 수없는 데이터를 필터링하십시오.
리버스 푸시 아웃 외부 사변형 범위
/*** 지정된 위도 및 경도에서 포인트의 4 개의 정점의 위도와 경도를 얻습니다. {@code radius} km의 외부 사변형 (엄격하게 말하면 외부 큐브가되어야 함)** @param lng longitude* @param lat latitude* @param radius, init : km*/lat2, lat1, lat1, lat1, lat1 tuple4 <bouble> calcboxbydistfrompt (double lng, double lat, double radius) {spatialContext context = spatialContext.geo; 사각형 사각형 = context.getDistCalc () // .CalcboxByDistFrompt (// context.MakePoint (lng, lat), // radius * com.spatial4j.core.distance.distanceutils.km_to_deg, context, null //); new tuple4 <> (사각형 .getminx (), 사각형.getmaxx (), rectangle.getminy (), rectangle.getmaxy ());}를 반환합니다.여기에 사용 된 Maven 좌표는 다음과 같습니다.
<pectionency> <groupid> com.spatial4j </groupid> <artifactid> spatial4j </artifactid> <버전> 0.5 </version> </fectionency>
현재 SQL을 변경할 수 있습니다.
@TARGETLAT = 31.175702; SET @TARGETLNG = 121.519095; SELECT S.ID, S.NAME, S.LNG, S.LAT (6378.138 * 2 * ASIN) @TargetLat * pi () / 180) * cos (s.lat * pi () / 180) * pow (sin ((@targetlng * pi () / 180 -s.lng * pi () / 180) / 2), 2))) * 1000) station swhere (s.lng 사이의 s.lng}) 및 $ {s.l})). 거리 ASC, S.Idlimit 20에 의한 $ {lat1} 및 $ {lat2}) 순서;상기 LNG1, LNG2, LAT1, LAT2는 외부 사변형의 범위입니다.
인용 정보 : http://blog.csdn.net/a364572/article/details/50483568
샘플 소스 코드
서비스 : https : //github.com/hylexus/bl ...
데이터 초기화 : https : //github.com/hylexus/bl ...
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.