用 AI 写了一个经纬度格式转换工具,从需求到落地的完整过程
ç¨ AI åäºä¸ä¸ªç»çº¬åº¦æ ¼å¼è½¬æ¢å·¥å ·ï¼ä»éæ±å°è½å°ç宿´è¿ç¨
éé¯ 2026-08-18 0 é 读10åéæè¿å¨åä¸ä¸ªå°çç¸å ³çå é¨å·¥å ·æ¶ï¼é¢ç¹éè¦å¤çç»çº¬åº¦æ ¼å¼è½¬æ¢åè·ç¦»è®¡ç®çé®é¢ãæ¯æ¬¡é½è¦æå¼åç§å¨çº¿å·¥å ·ï¼æ¥å忢页é¢ï¼å®å¨éº»ç¦ãæ£å¥½æè¿å¨å°è¯ç¨ AI è¾ å©å¼åï¼å°±æ³çè½ä¸è½è®© AI 帮æå¿«éå®ç°ä¸ä¸ªèªç¨çå·¥å ·ã
为ä»ä¹ä¼æè¿ä¸ªéæ±
åå°å¾ç¸å
³çå¼åï¼ç»å¸¸ä¼éå°è¿æ ·çåºæ¯ï¼ä»æ°æ®åºé导åºçåæ æ¯åè¿å¶åº¦æ ¼å¼ï¼æ¯å¦ 39.9042ï¼ï¼ä½å®¢æ·è¦æ±å±ç¤ºä¸ºåº¦åç§æ ¼å¼ï¼æ¯å¦ 39°54'15.12"Nï¼ãåè¿æ¥ï¼ä» GPS 设å¤è·åçåæ å¯è½æ¯ DMS æ ¼å¼ï¼éè¦è½¬æ DD æ ¼å¼æè½åå¨ã
以åæçåæ³æ¯ï¼æå¼æç´¢å¼æï¼æ¾ä¸ªå¨çº¿è½¬æ¢å·¥å ·ï¼å¤å¶ç²è´´ï¼åå¤å¶åæ¥ãè¿ä¸ªè¿ç¨æ¥å忢页é¢ï¼æçå¾ä½ãèä¸å¾å¤å¨çº¿å·¥å ·è¿å¸¦å¹¿åï¼é¡µé¢å è½½ä¹æ ¢ã
忥æ³çï¼æ¢ç¶èªå·±ä¼å代ç ï¼ä¸ºä»ä¹ä¸åä¸ä¸ªèªç¨çå·¥å ·å¢ï¼æ£å¥½ä¹æ³è¯è¯ AI è¾ å©ç¼ç¨çææï¼å°±æäºè¿ä¸ªé¡¹ç®ã
ä¼ ç»æ¹æ¡çé®é¢
å¨å¨æä¹åï¼æå ¶å®èèè¿å ä¸ªæ¹æ¡ï¼
æ¹æ¡ä¸ï¼ç´æ¥ç¨ç°æçå¨çº¿å·¥å ·
- ä¼ç¹ï¼é¶ææ¬ï¼æå¼å³ç¨
- 缺ç¹ï¼éè¦åæ¢é¡µé¢ï¼æ°æ®éè¦å¤å¶ç²è´´ï¼ä¸è½æ¹éå¤çï¼è䏿äºå·¥å ·è¿éæµ
æ¹æ¡äºï¼åä¸ä¸ªå½ä»¤è¡èæ¬
- ä¼ç¹ï¼å¯ä»¥æ¹éå¤çï¼é度快
- 缺ç¹ï¼ä¸å¤ç´è§ï¼æ¯æ¬¡é½è¦æå¼ç»ç«¯ï¼èä¸ä¸æ¹ä¾¿ç»å¢éå ¶ä»äººç¨
æ¹æ¡ä¸ï¼åä¸ä¸ªç®åç Web å·¥å ·
- ä¼ç¹ï¼å¯è§åæä½ï¼æ¹ä¾¿å享ï¼å¯ä»¥éæå°å é¨ç³»ç»ä¸
- 缺ç¹ï¼éè¦è±æ¶é´å¼å
æç»éæ©äºæ¹æ¡ä¸ï¼å 为èèå°è¿ä¸ªå·¥å ·å¯è½ä¸æ¢æèªå·±ç¨ï¼å¢ééå ¶ä»äººä¹éè¦ï¼Web 页颿¯æå好çå½¢å¼ã
AI è¾ å©å¼åçè¿ç¨
说å®è¯ï¼ä¸å¼å§æå¯¹ AI åä»£ç æ¯ææçæåº¦çãæ¯ç«ä»¥åç¨ AI åç代ç ï¼ç»å¸¸åºç°é»è¾é误æè 飿 ¼ä¸ä¸è´çé®é¢ãä½è¿æ¬¡æå³å®è®¤çè¯ä¸æ¬¡ï¼ççè½ä¸è½é å AI 宿ä¸ä¸ªå®æ´çå·¥å ·ã
第ä¸è½®ï¼éæ±æè¿°
æç¨çæç¤ºè¯å¤§æ¦æ¯è¿æ ·çï¼
ä½ æ¯ä¸åèµæ·±å端工ç¨å¸ãè¯·æ ¹æ®ä¸æ¹è§æ ¼ï¼çæä¸ä¸ªç¬ç«çåæä»¶ HTML å·¥å
·ã
è¦æ±ï¼
- ç产级å«ä»£ç ï¼è´¨éé«ï¼å¯è¯»æ§å¼º
- ä¸¥æ ¼å®ç°ãåè½å表ãä¸çææåè½ï¼ä¸å¾çç¥ãä¸å¾ç¨ placeholder 代æ¿
- ææç¨æ·å¯è§ææ¡å¿
é¡»ä½¿ç¨ i18n æºå¶
ç¶åååºäºè¯¦ç»çåè½å表ï¼å æ¬ï¼
- DDâDMS 转æ¢
- DMSâDD 转æ¢
- ååè¾å ¥ï¼èªå¨è®¡ç®
- åçæ è¯èªå¨å¤æ
- Haversine å ¬å¼è®¡ç®è·ç¦»
- æ¹ä½è§è®¡ç®
- 常ç¨åå¸åæ 鿥
- ä¸é®å¤å¶ç»æ
第äºè½®ï¼AI 代ç çé®é¢
AI ç¬¬ä¸æ¬¡çæç代ç ï¼æ´ä½ç»æè¿ä¸éï¼ä½æå 个é®é¢ï¼
é®é¢ä¸ï¼è¾å ¥æ¡èå¨é»è¾ä¸å®å
AI çæç代ç ä¸ï¼DD è¾å
¥æ¡ç oninput äºä»¶åªè§¦åäº onDDChange()ï¼è DMS è¾å
¥æ¡çäºä»¶åªè§¦åäº onDMSChange()ãä½å®é
使ç¨ä¸ï¼ç¨æ·å¯è½ä¼å¨ä¸¤ä¸ªè¾å
¥æ¡ä¸æ¥å忢ï¼éè¦ç¡®ä¿ä¸¤è¾¹æ°æ®å§ç»åæ¥ã
function onDDChange(){
var lat=parseFloat(document.getElementById('ddLat').value);
var lon=parseFloat(document.getElementById('ddLon').value);
updateHemispheres();
if(!isNaN(lat)){
document.getElementById('dmsLat').value=ddToDmsStr(lat,true);
}else{
document.getElementById('dmsLat').value='';
}
// ... çç¥
}
é®é¢äºï¼DMS è§£æä¸å¤å¥å£®
AI çæç dmsStrToDd 彿°ï¼è½ç¶è½å¤çæ åæ ¼å¼ï¼ä½éå°ä¸äºç¹æ®æ
åµå°±ä¼åºéãæ¯å¦ç¨æ·è¾å
¥ 39°54'15.12" å 39 54 15.12 è¿ç§æ ¼å¼ä¸åçæ
åµï¼éè¦ç»ä¸å¤çã
function dmsStrToDd(str){
// ... çç¥
// éè¦å¤çå¤ç§åé符ï¼Â°ã'ã"ï¼ä»¥åç©ºæ ¼
var normalized=str.replace(/[\u00b0\u00ba\u2218]/g,' ').replace(/['\u2019\u2032"]/g,' ').replace(/[\u2033\u201d]/g,' ').trim();
parts=normalized.split(/[\s,]+/).filter(function(p){return p.length>0;});
// ... çç¥
}
é®é¢ä¸ï¼ç¼ºå°è¾å ¥æ ¡éª
AI çæç代ç ï¼å¯¹æç«¯è¾å ¥ï¼æ¯å¦è¶ è¿ 90 度æ 180 度çç»çº¬åº¦ï¼æ²¡æåæ ¡éªãè½ç¶è¿ä¸æ¯æ ¸å¿åè½ï¼ä½ä½ä¸ºä¸ä¸ªçäº§çº§å·¥å ·ï¼åºè¯¥è¦æåºæ¬çè¾å ¥æ£æ¥ã
第ä¸è½®ï¼ä¸ AI ç对è¯è°ä¼
åç°é®é¢åï¼æå AI è¿è¡äºå¤è½®å¯¹è¯ï¼
æï¼ "DMS è§£æå½æ°éè¦å¤çæ´å¤æ ¼å¼ï¼æ¯å¦ 39 54 15.12 è¿ç§ç©ºæ ¼åéçæ ¼å¼ï¼è¿æ 39°54'15.12" è¿ç§æ åæ ¼å¼ã"
AIï¼ "好çï¼ææ¥ä¼åè§£æé»è¾ãæä¼ç»ä¸å¤çåç§åé符ï¼å¹¶å¢å æ ¼å¼æ ¡éªã"
æï¼ "è¾å ¥æ¡éè¦å 鲿å¤çï¼é¿å ç¨æ·è¿ç»è¾å ¥æ¶é¢ç¹è§¦å计ç®ã"
AIï¼ "æç½ï¼æä¼å¢å ä¸ä¸ªé²æå½æ°ï¼å»¶è¿ 300ms æ§è¡è®¡ç®é»è¾ã"
æï¼ "åå¸åæ æé®ç¹å»åï¼éè¦åæ¶æ´æ° DD å DMS 两个è¾å ¥æ¡ã"
AIï¼ "好çï¼æä¼å¨ applyCity 彿°ä¸åæ¶æ´æ°ä¸¤ä¸ªè¾å
¥æ¡çå¼ã"
éè¿å 轮对è¯ï¼AI 䏿å®å代ç ãä½è¯´å®è¯ï¼AI çæç代ç è¿æ¯éè¦äººå·¥æ£æ¥çãæ¯å¦å®å¯¹ NaN çå¤çã对空å¼çå¤æï¼ææ¶åä¸å¤ä¸¥è°¨ãè¿äºå°æ¹æé½éè¦æå¨ä¿®æ¹ã
æ ¸å¿ææ¯å®ç°
DD â DMS 转æ¢
è¿ä¸ªè½¬æ¢é»è¾å ¶å®å¾ç®åï¼
function ddToDmsStr(dd, isLat) {
var hemi = isLat ? (dd >= 0 ? 'N' : 'S') : (dd >= 0 ? 'E' : 'W');
dd = Math.abs(dd);
var d = Math.floor(dd);
var mFloat = (dd - d) * 60;
var m = Math.floor(mFloat);
var s = (mFloat - m) * 60;
return d + '°' + String(m).padStart(2, '0') + '\'' + s.toFixed(2).padStart(5, '0') + '"' + hemi;
}
è¿éæå 个ç»èéè¦æ³¨æï¼
- è¦å åç»å¯¹å¼ï¼å计ç®åº¦åç§
- ååç§è¦ç¨
padStartè¡¥é¶ï¼ä¿è¯æ ¼å¼ç»ä¸ - åçæ è¯æ ¹æ®æ£è´å¤æ
DMS â DD 转æ¢
åå转æ¢ç¨å¾®å¤æä¸ç¹ï¼å 为è¦å¤çåç§è¾å ¥æ ¼å¼ï¼
function dmsStrToDd(str) {
// å¤çè´å·ååçæ è¯
// ç»ä¸åé符
var normalized = str.replace(/[°ºË]/g, ' ').replace(/[''']/g, ' ').replace(/[""]/g, ' ').trim();
var parts = normalized.split(/[\s,]+/).filter(function(p) { return p.length > 0; });
// 妿æ¯å个æ°åï¼ç´æ¥å½ä½åè¿å¶åº¦
if (parts.length === 1) {
return parseFloat(parts[0]);
}
// å¦åæåº¦åç§è§£æ
var d = parseFloat(parts[0]);
var m = parseFloat(parts[1]);
var s = parts.length >= 3 ? parseFloat(parts[2]) : 0;
return d + m / 60 + s / 3600;
}
è¿é踩è¿ä¸ä¸ªåï¼åº¦åç§çç¬¦å· Â° å¨ Unicode 䏿å¤ç§è¡¨ç¤ºæ¹å¼ï¼\u00b0ã\u00baã\u2218ï¼ï¼éè¦ç»ä¸å¤çãAI ä¸å¼å§åªå¤çäº \u00b0ï¼å¯¼è´å
¶ä»ç¬¦å·æ æ³è§£æã
Haversine è·ç¦»è®¡ç®
è·ç¦»è®¡ç®ç¨çæ¯ Haversine å ¬å¼ï¼è¿æ¯çé¢è·ç¦»è®¡ç®çæ åæ¹æ³ï¼
function haversine(lat1, lon1, lat2, lon2) {
var dLat = toRad(lat2 - lat1);
var dLon = toRad(lon2 - lon1);
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R_EARTH * c;
}
å°çåå¾å 6371 kmï¼è¿ä¸ªå¼å¨å¤§å¤æ°åºæ¯ä¸ç²¾åº¦è¶³å¤ã
æ¹ä½è§è®¡ç®
æ¹ä½è§è®¡ç®ç¨å¾®å¤æä¸äºï¼éè¦ç¨å° atan2 彿°ï¼
function bearing(lat1, lon1, lat2, lon2) {
var y = Math.sin(toRad(lon2 - lon1)) * Math.cos(toRad(lat2));
var x = Math.cos(toRad(lat1)) * Math.sin(toRad(lat2)) -
Math.sin(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.cos(toRad(lon2 - lon1));
var brng = Math.atan2(y, x);
return (toDeg(brng) + 360) % 360;
}
注ææåè¦å 360 å忍¡ï¼ç¡®ä¿æ¹ä½è§å¨ 0-360° èå´å ã
设计å³ç
为ä»ä¹ç¨çº¯å端ï¼
è¿ä¸ªå·¥å ·ä¸éè¦å卿°æ®ï¼ä¹ä¸éè¦å端é»è¾ï¼çº¯å端å®å ¨å¤ç¨ãèä¸çº¯å端å¯ä»¥å è´¹é¨ç½²å¨éæé¡µé¢ä¸ï¼ä¸éè¦ç»´æ¤æå¡å¨ã
为ä»ä¹ç¨åæä»¶ HTMLï¼
èèå°è¿ä¸ªå·¥å ·å¯è½ä¼è¢«å享ç»å¢éå ¶ä»äººä½¿ç¨ï¼åæä»¶ HTML æ¯ææ¹ä¾¿çå½¢å¼ãç´æ¥æå¼æµè§å¨å°±è½ç¨ï¼ä¸éè¦å®è£ ä»»ä½ä¾èµã
为ä»ä¹æ¯æä¸è±æåæ¢ï¼
è½ç¶ä¸»è¦æ¯èªå·±ç¨ï¼ä½èèå°å¢ééå¯è½æå¤ç±åäºï¼èä¸ä½ä¸ºå¨çº¿å·¥å ·åå¸åå¯è½è¢«æ´å¤äººä½¿ç¨ï¼æä»¥åäº i18nã
为ä»ä¹ç¨ CSS åéå主é¢ï¼
CSS åéé
å prefers-color-scheme åªä½æ¥è¯¢ï¼å¯ä»¥èªå¨éé
ç³»ç»çæ·±è²æ¨¡å¼ï¼ä¸éè¦æå¨åæ¢ã
踩åè®°å½
åä¸ï¼input[type="number"] çæ»å¨æ¡é®é¢
å¨ Chrome ä¸ï¼input[type="number"] çä¸ä¸ç®å¤´æé®ä¼å ç¨ç©ºé´ï¼å¯¼è´è¾å
¥æ¡çèµ·æ¥ä¸æ´é½ãè§£å³æ¹æ¡æ¯éèé»è®¤çæ»å¨æ¡ï¼
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type="number"] {
-moz-appearance: textfield;
}
åäºï¼å¤å¶å°åªè´´æ¿çå ¼å®¹æ§
navigator.clipboard.writeText() å¨é HTTPS ç¯å¢ä¸ä¸å¯ç¨ï¼éè¦éçº§å° document.execCommand('copy')ãè½ç¶ç°å¨åºæ¬é½æ¯ HTTPS äºï¼ä½ä¸ºäºå
¼å®¹æ§è¿æ¯åäº fallbackã
åä¸ï¼DMS æ ¼å¼çå符串解æ
ç¨æ·è¾å
¥ DMS æ ¼å¼æ¶ï¼å¯è½ä¼ç¨åç§ç¬¦å·åéãæ¯å¦ 39°54'15.12"ã39 54 15.12ã39-54-15.12 çãéè¦ç»ä¸å¤çè¿äºæ ¼å¼ã
ä½¿ç¨ AI è¾ å©å¼åçæå
è¿æ¬¡ç¨ AI è¾ å©å¼åï¼æ´ä½ä½éªè¿æ¯ä¸éçãAI 帮æèçäºå¤§é¨åç¼ç æ¶é´ï¼å°¤å ¶æ¯å¨ HTML/CSS å¸å±ååºç¡é»è¾å®ç°ä¸ãä½å®ä¹æææ¾ççæ¿ï¼
- 对边ççå¤çä¸å¤ä¸¥è°¨ï¼AI çæç代ç ï¼å¯¹ç©ºå¼ãNaNãç¹æ®å符çå¤çç»å¸¸æé®é¢ï¼éè¦äººå·¥æ£æ¥åè¡¥å ã
- 对ä¸å¡é»è¾ççè§£ä¸å¤æ·±å ¥ï¼æ¯å¦ DMS æ ¼å¼çå¤ç§åä½ï¼AI ä¸å¼å§åªå¤çäºæ åæ ¼å¼ï¼éè¦ææç¤ºæä¼è¡¥å ã
- 代ç 飿 ¼ä¸å¤ç»ä¸ï¼AI çæç代ç ï¼åéå½åå彿°ç»ç»æ¹å¼å¯è½ä¸ä¸è´ï¼éè¦æ´çã
æç建议æ¯ï¼æ AI 彿ä¸ä¸ªé«çº§ç代ç çæå¨ï¼è䏿¯ä¸ä¸ªå®å ¨èªä¸»çå¼åè ãç¨çæ¶åè¦ç»åºæç¡®çéæ±åéªæ¶æ åï¼çæåè¦è®¤ç review 代ç ï¼å°¤å ¶æ¯è¾¹çæ åµã
æç»ææ
å·¥å ·å®æåï¼ç¨èµ·æ¥ç¡®å®æ¹ä¾¿å¤äºï¼
- è¾å ¥åè¿å¶åº¦ï¼èªå¨è½¬æ¢åº¦åç§
- è¾å ¥åº¦åç§ï¼èªå¨è½¬æ¢åè¿å¶åº¦
- éæ©ä¸¤ä¸ªåå¸ï¼èªå¨è®¡ç®è·ç¦»åæ¹ä½è§
- æ¯æä¸è±æåæ¢
- æ¯ææ·±è²æ¨¡å¼
æ´ä¸ªå·¥å ·æ¯ä¸ä¸ªåæä»¶ HTMLï¼å¯ä»¥ç´æ¥æå¼ä½¿ç¨ï¼ä¹å¯ä»¥é¨ç½²å°éææå¡å¨ä¸ã
éç¨åºæ¯
è¿ä¸ªå·¥å ·éå以ä¸åºæ¯ï¼
- å°å¾å¼åè°è¯ï¼éè¦å¿«éæ¥çåæ æ ¼å¼è½¬æ¢ç»æ
- GPS æ°æ®å¤çï¼éè¦æ¹é转æ¢åæ æ ¼å¼
- å°çæå¦æ¼ç¤ºï¼å±ç¤º DD å DMS æ ¼å¼çå ³ç³»
- ç©æµè·¯å¾è§åï¼è®¡ç®ä¸¤ä¸ªå°ç¹çç´çº¿è·ç¦»åæ¹å
å¦æä½ ä¹æç±»ä¼¼çéæ±ï¼å¯ä»¥å¨çº¿ä½éªï¼å°çç¼ç æ¼ç¤º - å¨çº¿ç»çº¬åº¦æ ¼å¼è½¬æ¢å·¥å ·
æ»ç»
è¿æ¬¡ç¨ AI è¾ å©å¼åå°å·¥å ·çç»åï¼è®©æå¯¹ AI ç¼ç¨æäºæ°ç认è¯ãAI ç¡®å®è½æé«å¼åæçï¼ä½åææ¯ä½ è¦ææ¸ æ°çæè·¯åä¸¥æ ¼çéæ±æè¿°ãä¸å ¶è¯´ AI å¸®ä½ å代ç ï¼ä¸å¦è¯´ AI å¸®ä½ ææ³æ³å¿«éåæç°å®ã
æåæ³è¯´ï¼ä¸ç®¡ç¨ä»ä¹å·¥å ·ï¼æ ¸å¿è¿æ¯ä½ 对ä¸å¡ççè§£å对代ç è´¨éçè¦æ±ãAI åªæ¯ä¸ªå éå¨ï¼ä¸è½æ¿ä»£ä½ ç夿åã
Aitishiku.com