void BitmapLoader::doLoadManifest() { wxString targetFile; if(ExtractFileFromZip( m_zipPath.GetFullPath(), wxT("manifest.ini"), clStandardPaths::Get().GetUserDataDir(), targetFile)) { // we got the file extracted, read it wxFileName manifest(targetFile); wxFFile fp(manifest.GetFullPath(), wxT("r")); if(fp.IsOpened()) { wxString content; fp.ReadAll(&content); m_manifest.clear(); wxArrayString entries = wxStringTokenize(content, wxT("\n"), wxTOKEN_STRTOK); for(size_t i = 0; i < entries.size(); i++) { wxString entry = entries[i]; entry.Trim().Trim(false); // empty? if(entry.empty()) continue; // comment? if(entry.StartsWith(wxT(";"))) continue; wxString key = entry.BeforeFirst(wxT('=')); wxString val = entry.AfterFirst(wxT('=')); key.Trim().Trim(false); val.Trim().Trim(false); wxString key16, key24; key16 = key; key24 = key; key16.Replace(wxT("<size>"), wxT("16")); key24.Replace(wxT("<size>"), wxT("24")); key16.Replace(wxT("."), wxT("/")); key24.Replace(wxT("."), wxT("/")); m_manifest[key16] = val; m_manifest[key24] = val; } fp.Close(); wxRemoveFile(manifest.GetFullPath()); } wxRemoveFile(targetFile); } }
wxBitmap BitmapLoader::doLoadBitmap(const wxString& filepath) { wxString bitmapFile; if(ExtractFileFromZip(m_zipPath.GetFullPath(), filepath, clStandardPaths::Get().GetUserDataDir(), bitmapFile)) { clBitmap bmp; if(bmp.LoadFile(bitmapFile, wxBITMAP_TYPE_PNG)) { wxRemoveFile(bitmapFile); return bmp; } wxRemoveFile(bitmapFile); } return wxNullBitmap; }
SURF_FETCH_E LandfireClient::FetchBoundingBox( double *bbox, double resolution, const char *filename, char **options ) { (void)resolution; if( NULL == filename ) { return SURF_FETCH_E_BAD_INPUT; } /* ** We have an arbitrary limit on request size, 0.001 degrees */ if( fabs( bbox[0] - bbox[2] ) < 0.001 || fabs( bbox[1] - bbox[3] ) < 0.001 ) { CPLError( CE_Failure, CPLE_AppDefined, "Bounding box too small, must be greater than " \ "0.001 x 0.001 degrees." ); return SURF_FETCH_E_BAD_INPUT; } /*----------------------------------------------------------------------------- * Local Variable Declarations *-----------------------------------------------------------------------------*/ int i = 0; char *p; int nMaxTries = atoi( CPLGetConfigOption( "LCP_MAX_DOWNLOAD_TRIES", "40" ) ); double dfWait = atof( CPLGetConfigOption( "LCP_DOWNLOAD_WAIT", "3" ) ); const char *pszProduct = CPLStrdup( CSLFetchNameValue( options, "PRODUCT" ) ); /* ** Stupidly simple heuristics to try to get the 'correct' product. */ if( pszProduct == NULL || EQUAL( pszProduct, "" ) ) { if( EQUAL( pszProduct, "" ) ) CPLFree( (void*)pszProduct ); std::string osDataPath = FindDataPath( "landfire.zip" ); osDataPath = "/vsizip/" + osDataPath; const char *pszGeom; pszGeom = CPLSPrintf( "POLYGON((%lf %lf,%lf %lf,%lf %lf,%lf %lf,%lf %lf))", bbox[1], bbox[0], bbox[3], bbox[0], bbox[3], bbox[2], bbox[1], bbox[2], bbox[1], bbox[0] ); CPLDebug( "LCP_CLIENT", "Testing if %s contains %s", osDataPath.c_str(), pszGeom ); if( NinjaOGRContain( pszGeom, osDataPath.c_str(), "conus" ) ) { pszProduct = CPLStrdup( "F4W21HZ" ); } else if( NinjaOGRContain( pszGeom, osDataPath.c_str(), "ak" ) ) { pszProduct = CPLStrdup( "F7C29HZ" ); } else if( NinjaOGRContain( pszGeom, osDataPath.c_str(), "hi" ) ) { pszProduct = CPLStrdup( "F4825HZ" ); } /* Contiguous US */ //if( bbox[0] < 52 && bbox[1] < -60 && bbox[2] > 22 && bbox[3] > -136 ) // pszProduct = CPLStrdup( "F4W21HZ" ); /* Alaska */ //else if( bbox[0] < 75 && bbox[1] < -125 && bbox[2] > 50 && bbox[3] > -179 ) // pszProduct = CPLStrdup( "F7C29HZ" ); /* Hawaii */ //else if( bbox[0] < 25 && bbox[1] < -150 && bbox[2] > 15 && bbox[3] > -170 ) // pszProduct = CPLStrdup( "F4825HZ" ); else { CPLError( CE_Failure, CPLE_AppDefined, "Failed to locate product." ); return SURF_FETCH_E_BAD_INPUT; } } CPLDebug( "LCP_CLIENT", "Using product: %s", pszProduct ); const char *pszUrl; const char *pszTemp = CSLFetchNameValue( options, "OVERRIDE_BEST_UTM" ); int nEpsgCode = -1; if( pszTemp == NULL ) { nEpsgCode = BoundingBoxUtm( bbox ); } else { nEpsgCode = atoi( pszTemp ); } /* ** Better check? */ if( nEpsgCode < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid EPSG code." ); CPLFree( (void*)pszProduct ); return SURF_FETCH_E_BAD_INPUT; } /*----------------------------------------------------------------------------- * Request a Model via the landfire.cr.usgs.gov REST client *-----------------------------------------------------------------------------*/ pszUrl = CPLSPrintf( LF_REQUEST_TEMPLATE, bbox[0], bbox[2], bbox[3], bbox[1], pszProduct ); CPLFree( (void*)pszProduct ); m_poResult = CPLHTTPFetch( pszUrl, NULL ); CHECK_HTTP_RESULT( "Failed to get download URL" ); CPLDebug( "LCP_CLIENT", "Request URL: %s", pszUrl ); /*----------------------------------------------------------------------------- * Parse the JSON result of the request *-----------------------------------------------------------------------------*/ int nSize = strlen( (char*) m_poResult->pabyData ); //Create a buffer so we can use sscanf, couldn't find a CPL version char *pszResponse = new char[ nSize + 1 ]; pszResponse[0] = '\0'; CPLDebug( "LCP_CLIENT", "JSON Response: %s", m_poResult->pabyData ); /* ** Regular expression support if we have C++11 support. isnan ambiguouity ** is causing non-C++11 compliance. Not tested or used, 0 disables. */ #if __cplusplus >= 201103 && 0 std::string s((const char*) m_poResult->pabyData ); std::smatch m; std::regex e( "\\b(?:(?:https?)://|www\\.)[a-z-A-Z0-9+&@#/%=~_|$?!:,.]" \ "*[a-z-A-Z0-9+&@#/%=~_|$]" ); std::regex_search( s, m, e ); std::string url = m[0].str(); //retrieve first match CPLStrlcpy( pszResponse, url.c_str(), nSize ); #else char **papszTokens = NULL; papszTokens = CSLTokenizeString2( (const char*)m_poResult->pabyData, ",:", CSLT_HONOURSTRINGS | CSLT_PRESERVEESCAPES | CSLT_STRIPENDSPACES | CSLT_STRIPLEADSPACES ); int nTokens = CSLCount( papszTokens ); if( nTokens < 2 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to generate valid URL for LCP download." ); delete [] pszResponse; CPLHTTPDestroyResult( m_poResult ); CSLDestroy( papszTokens ); return SURF_FETCH_E_IO_ERR; } for( int i = 1; i < nTokens; i++ ) { if( EQUALN( papszTokens[i], "https://", 6 ) && EQUAL( papszTokens[i - 1], "DOWNLOAD_URL" ) ) { CPLStrlcpy( pszResponse, papszTokens[i], nSize ); break; } } CSLDestroy( papszTokens ); #endif //Grab the download URL from the JSON response, stores in pszResponse //std::sscanf( (char*) m_poResult->pabyData, LF_REQUEST_RETURN_TEMPLATE, pszResponse); CPLHTTPDestroyResult( m_poResult ); if( !EQUALN( pszResponse, "https://", 6 ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to generate valid URL for LCP download." ); delete [] pszResponse; return SURF_FETCH_E_IO_ERR; } p = strstr( pszResponse, "}]" ); if( p ) *p = '\0'; CPLDebug( "LCP_CLIENT", "Download URL: %s", pszResponse ); // Fix the SRS const char *pszNewUrl = ReplaceSRS( nEpsgCode, pszResponse ); CPLDebug( "LCP_CLIENT", "Sanitized SRS Download URL: %s", pszNewUrl ); /*----------------------------------------------------------------------------- * Get the Job ID by visiting the download URL *-----------------------------------------------------------------------------*/ m_poResult = CPLHTTPFetch( pszNewUrl, NULL ); CPLFree( (void*)pszNewUrl ); delete [] pszResponse; CHECK_HTTP_RESULT( "Failed to get Job ID" ); nSize = strlen( (char*) m_poResult->pabyData ); pszResponse = new char[ nSize + 1 ]; //grabs the Job ID from the Download URL response std::sscanf( (char*) m_poResult->pabyData, LF_INIT_RESPONSE_TEMPLATE, pszResponse); CPLHTTPDestroyResult( m_poResult ); //store the Job Id into a class attribute, so we can reuse pszResponse, but keep //the Job Id (needed for future parts) m_JobId = std::string( pszResponse ); CPLDebug( "LCP_CLIENT", "Job id: %s", m_JobId.c_str() ); /*----------------------------------------------------------------------------- * Initiate the download by using the obtained Job ID *-----------------------------------------------------------------------------*/ pszUrl = CPLSPrintf( LF_INIT_DOWNLOAD_TEMPLATE, m_JobId.c_str() ); //fetch the response of download initiation //note: for some reason it alway returns a key error, but download still works m_poResult = CPLHTTPFetch( pszUrl, NULL ); CPLHTTPDestroyResult( m_poResult ); /*----------------------------------------------------------------------------- * Check the status of the download, able to download when status=400 *-----------------------------------------------------------------------------*/ int dl_status = 0; //Obtain the readiness status of the current job pszUrl = CPLSPrintf( LF_GET_STATUS_TEMPLATE, m_JobId.c_str() ); CPLDebug( "LCP_CLIENT", "Status url: %s", pszUrl ); do { m_poResult = CPLHTTPFetch( pszUrl, NULL ); delete [] pszResponse; CHECK_HTTP_RESULT( "Failed to get job status" ); nSize = strlen( (char*) m_poResult->pabyData ); pszResponse = new char[ nSize + 1 ]; std::sscanf( (char*) m_poResult->pabyData, LF_STATUS_RESPONSE_TEMPLATE, &dl_status, pszResponse ); CPLHTTPDestroyResult( m_poResult ); i++; CPLSleep( dfWait ); CPLDebug( "LCP_CLIENT", "Attempting to fetch LCP, try %d of %d, " \ "status: %d", i, nMaxTries, dl_status ); } while( dl_status < 400 && dl_status > 0 && i < nMaxTries ); delete [] pszResponse; if( dl_status >= 900 && dl_status <= 902) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to download lcp," \ "There was an extraction " \ "error on the server." ); return SURF_FETCH_E_IO_ERR; } else if( dl_status != 400 ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to download lcp, timed " \ "out. Try increasing " \ "LCP_MAX_DOWNLOAD_TRIES or " "LCP_DOWNLOAD_WAIT" ); return SURF_FETCH_E_TIMEOUT; } /*----------------------------------------------------------------------------- * Download the landfire model *-----------------------------------------------------------------------------*/ pszUrl = CPLSPrintf( LF_DOWNLOAD_JOB_TEMPLATE, m_JobId.c_str() ); m_poResult = CPLHTTPFetch( pszUrl, NULL ); CHECK_HTTP_RESULT( "Failed to get job status" ); /* ** Parse the URL from the returned string */ std::string ss((const char*) m_poResult->pabyData ); CPLHTTPDestroyResult( m_poResult ); std::size_t pos1 = ss.find("https://"); std::size_t pos2 = ss.find(".zip"); std::string url = ss.substr(pos1, (pos2+4-pos1)); pszUrl = url.c_str(); m_poResult = CPLHTTPFetch( pszUrl, NULL ); CHECK_HTTP_RESULT( "Failed to get job status" ); nSize = m_poResult->nDataLen; VSILFILE *fout; const char *pszTmpZip = CPLFormFilename( NULL, CPLGenerateTempFilename( "NINJA_LCP_CLIENT" ), ".zip" ); fout = VSIFOpenL( pszTmpZip, "w+" ); if( NULL == fout ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to create output file" ); CPLHTTPDestroyResult( m_poResult ); return SURF_FETCH_E_IO_ERR; } VSIFWriteL( m_poResult->pabyData, nSize, 1, fout ); VSIFCloseL( fout ); CPLHTTPDestroyResult( m_poResult ); /* ** Extract the lcp and the prj file, and 'save as' */ char **papszFileList = NULL; std::string osPathInZip; const char *pszVSIZip = CPLSPrintf( "/vsizip/%s", pszTmpZip ); CPLDebug( "LCP_CLIENT", "Extracting lcp from %s", pszVSIZip ); papszFileList = VSIReadDirRecursive( pszVSIZip ); int bFound = FALSE; std::string osFullPath; for( int i = 0; i < CSLCount( papszFileList ); i++ ) { osFullPath = papszFileList[i]; if( osFullPath.find( "Landscape_1.lcp" ) != std::string::npos ) { osPathInZip = CPLGetPath( papszFileList[i] ); CPLDebug( "LCP_CLIENT", "Found lcp in: %s", osPathInZip.c_str() ); bFound = TRUE; break; } } CSLDestroy( papszFileList ); if( !bFound ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find lcp in archive" ); //VSIUnlink( pszTmpZip ); return SURF_FETCH_E_IO_ERR; } int nError = 0; const char *pszFileToFind = CPLSPrintf( "%s/Landscape_1.lcp", osPathInZip.c_str() ); nError = ExtractFileFromZip( pszTmpZip, pszFileToFind, filename ); if( nError ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to extract LCP from zip." ); VSIUnlink( pszTmpZip ); return SURF_FETCH_E_IO_ERR; } pszFileToFind = CPLSPrintf( "%s/Landscape_1.prj", osPathInZip.c_str() ); nError = ExtractFileFromZip( pszTmpZip, pszFileToFind, CPLFormFilename( CPLGetPath( filename ), CPLGetBasename( filename ), ".prj" ) ); if( nError ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to extract PRJ from zip." ); return SURF_FETCH_E_IO_ERR; } if( !CSLTestBoolean( CPLGetConfigOption( "LCP_KEEP_ARCHIVE", "FALSE" ) ) ) { VSIUnlink( pszTmpZip ); } return SURF_FETCH_E_NONE; }
//读取自身数据(call by work thead) bool _readPatchContents(void) { char szExeSelf[MAX_PATH] = {0}; ::GetModuleFileName(g_hInst, szExeSelf, MAX_PATH); FILE* fp = fopen(szExeSelf, "rb"); if(!fp) return false; do { if(0 != fseek(fp, g_nExeSize, SEEK_SET)) break; int nLen=0; //read version from if(1 != fread(&nLen, sizeof(int), 1, fp) || nLen>=32 ) break; if(nLen != fread(g_szVersionFrom, 1, nLen, fp)) break; normalizeVersion(g_szVersionFrom, g_szVersionFrom_nor, 64); //read version to if(1 != fread(&nLen, sizeof(int), 1, fp) || nLen>=32 ) break; if(nLen != fread(g_szVersionTo, 1, nLen, fp)) break; normalizeVersion(g_szVersionTo, g_szVersionTo_nor, 64); //create temp patch file char szTempPath[MAX_PATH]; GetTempPath(MAX_PATH, szTempPath); PathAppend(szTempPath, "TLBBPatch"); CreateDirectory(szTempPath, 0); _snprintf(g_szPatchZip, MAX_PATH, "%s\\tlbb-%s-%s.xzip", szTempPath, g_szVersionFrom, g_szVersionTo); FILE* fpWrite = fopen(g_szPatchZip, "wb"); if(!fpWrite) break; char szTempBuf[1024] = {0}; do { size_t nReadSize = fread(szTempBuf, 1, 1024, fp); if(nReadSize==0) break; fwrite(szTempBuf, 1, nReadSize, fpWrite); if(feof(fp)) break; }while(true); fclose(fpWrite); fclose(fp); //读取其中的PatchInfo文件内容 char szPatchInfoFile[MAX_PATH]; _snprintf(szPatchInfoFile, MAX_PATH, "%stlbb_patchinfo_%s_%s.txt", szTempPath, g_szVersionFrom, g_szVersionTo); AXP::IUpdater* pUpdater = AXP::createUpdater(); if(ExtractFileFromZip(pUpdater, g_szPatchZip, "Update.txt", szPatchInfoFile)) { FILE* fpPatch = fopen(szPatchInfoFile, "rb"); if(fpPatch) { fseek(fpPatch, 0, SEEK_END); int nSize = ftell(fpPatch); fseek(fpPatch, 0, SEEK_SET); char* pTxtBuf = new char[nSize+1]; memset(pTxtBuf, 0, nSize+1); fread(pTxtBuf, 1, nSize, fpPatch); fclose(fpPatch); fpPatch=0; //send to ui ::SendDlgItemMessage(g_hMainWnd, IDC_EDIT_PATCHINFO, WM_SETTEXT, 0, (LPARAM)pTxtBuf); delete[] pTxtBuf; pTxtBuf=0; ::DeleteFile(szPatchInfoFile); } } AXP::destroyUpdater(pUpdater); pUpdater=0; return true; }while(0); //error! fclose(fp); return false; }