이 글은 현재 영어로만 제공됩니다.

(아티클)

Cross-Ministry Campaign Data: Merging Survey Sheets, Deduplicating Venues, and Designing IDs

The campaign went from planning to finished development in under 2 months. One 15-column header collects every sheet, scripts merge venues and standardize IDs, rows are validated before import, and the front end reads the same data.

Polish Design engineering team・2026-10-20

Contents

The 2026 Taiwan Outdoor Education Season was a 22-week cross-ministry web campaign, with planning, design, and development completed in under 2 months. The Ministry of Education launched the campaign together with the Ministry of Culture, the National Park Service of the Ministry of the Interior, the Forestry and Nature Conservation Agency of the Ministry of Agriculture, the Ministry of Environment, the Ministry of Economic Affairs, the Hakka Affairs Council, the Tourism Administration of the Ministry of Transportation and Communications, the Ocean Affairs Council, and the Council of Indigenous Peoples, with a private organization also taking part. Each organization submitted its courses on the same 15-column survey form, 11 worksheets in all. The development team used a Python script to turn those worksheets into four tables for venues, courses, characters, and quiz questions, and a Node.js import script then validated each table row by row before writing to the database. The finished data has 187 venues, 476 courses, and 1,056 quiz questions, and the interactive map, course list, character cards, and announcements all use the same set of IDs.

The overall build scope is described under campaign platform and admin, and rewards and accounting are covered in accounting, abuse prevention, and budget controls for prize campaigns.

Fig. 1Survey sheets are cleaned and validated row by row before import, and the front end and outward-facing documents read the same data

10 ministries and a private organization

  • 11 worksheetsOne shared 15-column header
15-column survey forms

Development team

  • Python cleanup scriptColumn mapping, venue merging, date parsing, ID sorting
  • Master workbook, four worksheetsVenues, courses, characters, quiz questions
  • Node.js import scriptValidate in the first pass, write in the second
Venue IDs, course IDs, and cleaned fields

Campaign site and outward-facing documents

  • Interactive map and course listQuery by map extent, county or city, month, weekday, theme, and ministry
  • Character cardsGenerated in batches from the master workbook
  • Announcements and shareable copyReuse the same names and figures

Edit once, in the master workbookVenue names, course times, and similar content are changed at the source. After the script is rerun, the map, course list, and cards read the updated data.

Scope: venue, course, character, quiz, and announcement data used during the campaign

Merging survey sheets and mapping columns

The survey's 15 columns include course name, venue, map address, type, description, activity time, fee, registration contact, supervising authority, organizing unit, and recommended highlight. The script reads each sheet with pandas and keeps only the first 15 columns. It strips line breaks from the column names and maps each one to a fixed internal name by keyword (for example "google", "description", and "recommended highlight" in the original Chinese), notes which worksheet each row came from, and merges everything into one table, dropping the sample rows and the repeated header rows.

Original columnMaster columnCleanup rule
Course nameCourse name, course IDStrip line breaks and spaces, then look up the course ID in the mapping table by name
Venue, map addressVenue name, address, Google Maps linkUnify the spelling and create the venue, as described in the next section; the link is built from the address as a search URL
TypeCourse categoryOver twenty free-text options are mapped to 8 categories; ecology and environment is the largest, with 186 courses
Activity timeStart date, end date, weekdays open each week, time noteParsed by rule, as described in the section on activity dates
Registration contactRegistration methodA cell with a URL is labeled a registration link, one with only an email address a contact email, and one with a phone number a contact phone
Description, typeTagsMatch the name, description, and type against a keyword table; when nothing matches, use the category as the tag

After the merge, the data is split into a venue table and a course table. The venue table has one row per venue, the course table has one row per course, and the import links each course to its venue by venue ID. This follows the structure Wickham, 2014 describes for tidy datasets, with each variable in a column, each observation in a row, and each type of observational unit in its own table. Address, area, and owning organization appear only in the venue table, so a venue that hosts many courses still has a single address.

Team members filing cards into the drawers of a large cabinet

Matching and merging venues

The venue field is normalized first. Remarks in parentheses are removed, full-width commas become half-width, runs of spaces collapse into one, and the two common forms of the character for Taiwan are unified so that names match, with addresses restored to the official form at import. The normalized name is the venue key. Identical names are treated as one venue, and the address is taken from the first row that has one.

Venue deduplication is an instance of duplicate record detection. Elmagarmid et al., 2007 point out that the same entity often has two or more representations in a database and that duplicate records share no common key. The survey forms carry no shared venue ID, so the IDs come from matching rules. A merge table with 31 entries folds floors, halls, trails, and spelling variants within the same building or grounds into a main venue. A multi-location table with 18 entries assigns courses that list several locations to a main venue and records the others in the note, written as "Sites: includes ...".

Desktop screen recording: zooming from all of Taiwan to a single venue, with the venue name shown on hover.
Fig. 2The venue field of each course is assigned by one of three rules
  1. Read the venue fieldFrom the survey form of each organization
  2. NormalizeDrop remarks in parentheses, convert full-width to half-width, and unify the two forms of the character for Taiwan
  • Floors, halls, or trails in the same building or grounds
    Merge into the main venueThe sub-location goes into the course note as "Sites: ..."
  • One course lists several locations
    Assign to the main venueThe note states which other locations are included
  • Different physical locations
    Keep each as its own venue

Addresses are standardized separately. The formal address with county or city and street number is extracted from the parentheses, map URLs are removed, and house numbers written in Chinese numerals are converted to Arabic numerals (a number written with the Chinese numeral for five becomes 5). The Google Maps link is then built from the cleaned address. Venues fall into five areas: north, central, south, east, and outlying islands. The area comes from the course mapping table, and when no entry exists it is judged from the address by checking county and city names in the order outlying islands, north, central, south, east.

Each venue also has a GPS verification area. Coordinates are looked up first in a manually maintained coordinate table. For the rest, the Nominatim geocoder is called with the address, or with the venue name when the address returns nothing, at intervals of 1.1 seconds. A result must fall within latitude 21 to 27 and longitude 118 to 123, and is then converted into a rectangle sized by venue type. All 187 venues have a verification area. On-site verification uses the venue coordinates to calculate the distance to the user.

The owning organization, which is the supervising authority, is determined by which worksheet of the survey form a venue appears on. Each worksheet corresponds to one official organization name, and venue names are matched in this order: manual assignment, exact match, containment, and the first four characters. When a venue appears on two or more worksheets, a person decides based on course count and relevance. After the write, the script verifies that no other fields were touched and that the venue count in the ownership summary matches the venue table.

The table below is the resulting ownership summary. One venue can be a single tourism factory or an entire national park, so the verification area is converted according to venue type.

Supervising authorityVenue typesVenues
Ministry of Economic AffairsTourism factories and industrial parks56
Tourism Administration, Ministry of Transportation and CommunicationsScenic areas and visitor centers37
National Park Service, Ministry of the InteriorNational parks and nature reserves30
Ministry of CultureHistoric sites, museums, and cultural parks24
Ministry of EnvironmentEnvironmental education facilities17
Forestry and Nature Conservation Agency, Ministry of AgricultureForest recreation areas and nature education centers10
Ministry of EducationScience museums, parks, and a community6
Ocean Affairs CouncilMarine education venues3
Hakka Affairs CouncilHakka cultural parks2
Council of Indigenous PeoplesIndigenous cultural park1
Private organizationSeafood experience center1
Total11 worksheets187

Parsing activity dates

Activity time is a single cell of free text in the survey. The script interprets it with the rules in the table below, parsing weekdays and date ranges separately, and always restricts dates to April 1 through August 31.

How the survey writes itParsed result
Weekdays, such as every Saturday and Sunday, or weekdays and weekendsWritten to the weekly open days, with 1 through 7 for Monday through Sunday; weekdays are 1 through 5 and weekends are 6 and 7
A month range, such as April-AugustThe start date is the 1st of the first month and the end date is the last day of the last month; any explanation in parentheses goes into the time note
A single monthThe 1st through the last day of that month
Specific month/day datesThe earliest and latest dates become the start and end, and the original text of a multi-day activity goes into the time note
A description that mentions reservations, applications, or groupsOpen for the whole campaign period, with the original text in the time note
Any other textIf it mentions months from April to August, use that range; otherwise open for the whole campaign period, with the first 50 characters of the original text in the time note

The start date, end date, and weekdays are stored at import as a date and a JSON array. The front-end month filter checks whether the start-to-end interval overlaps the selected month, and the weekday filter checks whether the array contains the selected weekday. Both run in the server query.

Numbering and sorting

A course ID is made of an area code, a water-or-land code, and a serial number. N-W-01, for example, is the first number in the north, water category. The area codes N, C, S, E, and I stand for north, central, south, east, and outlying islands. The codes W and L stand for water and land and come from water-related keywords in the course name, description, type, and location: a hit on any keyword gives W, and everything else gets L. Sorting is fixed as area, then water or land, then serial number, and finally evolution level Lv1 to Lv3. The sorting script turns each row into a sort key of four numbers and, once the rows are sorted, checks each one to confirm that nothing moves backward.

The course table, mapping table, character table, and quiz table all use this ID. Importing characters finds the course and venue through the course ID, and importing quiz questions finds the character through its ID. Quiz questions likewise hang under character IDs. How the parts of the ID map to character artwork is covered in how a large campaign's character system is designed.

The character collection: the collection page explains the three stages, and the cards below show each character's name and level.
The character collection: the collection page explains the three stages, and the cards below show each character's name and level.

The character table records the venue ID, and the venue name on a card is looked up from the venue table at output time, so renaming a venue means editing one place. The W3C's Data on the Web Best Practices recommend that items in a dataset use persistent URIs as identifiers so that the items can be linked to data about the same place, person, or event in other datasets. The IDs here are internal to the campaign and have no URL form, but the principle is the same: the same course and the same venue are referred to by the same identifier in every table.

Featured courses and the weekly calendar

The last column of the survey lets each organization mark recommended highlights, and that column is the basis for choosing featured courses. The script first allocates slots in proportion to each area's course count, with at least one per area, and then picks the highest-scoring course from that area's candidates one at a time. A recommended highlight adds points first, and scores are then adjusted for the distribution of venues, types, and source organizations, which spreads the featured courses across different venues, themes, and organizations.

The marks for the selected courses are written back to the mapping table, and the matching characters are always set to the highest rarity. The schedule is stored separately as a weekly calendar in which each row records the course, source organization, character ID, open date, end date, and open week number. The back end keeps the calendar as date ranges plus a list of course IDs. When the front end requests this week's featured courses, the server finds the range that contains the current date in Taiwan time and returns that week's courses with the matching characters. How the weekly rhythm works together with the raffles is covered in the participation rhythm of a 22-week campaign.

Announcements and shareable copy

The campaign ran 22 weeks, so the announcements were laid out as a single overview before launch, about 37 in all, each with a publication date and a channel, and with fields that depend on actual data marked in red.

CategoryCountWhen published
Pre-campaign announcement1Teaser before launch
Milestone announcements6Launch, first featured courses open, summer special, mid-campaign ranking, final countdown, campaign end
Weekly raffle results21Weeks 2 through 22, published by 9 p.m. every Friday
Monthly raffle bonus previews5One each for April through August, with results included in the weekly raffle results
Prize claims and administration4Claim process, ranking review, final ranking results, reminder for unclaimed prizes
The end-of-campaign leaderboard page: a power ranking and an energy ranking, with prizes listed by rank range, matching the administrative announcements on prize claims and ranking review.
The end-of-campaign leaderboard page: a power ranking and an energy ranking, with prizes listed by rank range, matching the administrative announcements on prize claims and ranking review.

Copy for the organizations that help republish is also written in advance. The base is an activity description with a fixed structure, in this order: campaign information, highlights, prizes, steps to join, and contact information. It is then rewritten into versions for the website, the email newsletter, social posts, and other channels. Each ministry also has its own post that opens with its venue count and types: 30 national parks and nature reserves for the National Park Service of the Ministry of the Interior, for example, and 10 forest recreation areas and nature education centers for the Forestry and Nature Conservation Agency of the Ministry of Agriculture. The figures match the ownership summary. Outward-facing text always says over 180 venues and over 470 courses, so the same figures appear wherever an organization republishes it.

Row-by-row validation before import

The master workbook has four worksheets (venues, courses, characters, and quiz questions) that a Node.js script imports in that order, with each one linking to the IDs of the one before. Every import script runs in two passes. The first pass validates row by row and collects all errors; if any row fails, the whole batch stops and lists the row numbers and reasons. Only when everything passes does the second pass write rows one at a time, so a failed validation leaves the database without a single row written.

Fig. 3Import runs in two passes, and one failed row stops the whole batch from being written
  1. Read the worksheetConvert rows to records in column order
  2. First pass: validate row by rowCollect every error without stopping at the first one
  • All rows pass
    Second pass: write row by rowFill in the creation time and status columns at the same time
  • Any row fails
    The whole batch stopsList the row numbers and reasons; the database stays as it was
WorksheetChecks and handling in the first pass
VenuesID, name, address, map link, area, owning organization, and verification area are required; the area must be one of the five; IDs must be unique; the address must resolve to a county or city and a district
CoursesID, venue ID, name, category, and description are required; the venue ID must already exist; IDs must be unique; dates are converted to YYYY-MM-DD; weekdays and tags are converted to JSON arrays
CharactersCourse ID, name, and the three-part dialogue are required; rarity and the value for each stage must be integers of 0 or more; the course and venue are linked through the course ID
Quiz questionsThe character ID must already exist; the level must be 1 or 2; the answer must be A, B, or C; a character-and-level pair cannot repeat

Data changes and how the front end queries

All of the scripts can be rerun. A rerun reads the original worksheets, writes the master workbook, and checks each course one by one: the venue exists in the venue table, the start and end dates fall between April 1 and August 31, and every course has an ID and tags. Anything that fails is listed. Bulk changes are made in the master workbook followed by a rerun, while individual fields are edited one at a time in the admin, and each edit records the operator and what changed.

The map queries venues by the coordinates of the four corners of the visible area and returns the courses and characters in each venue at the same time. The filters are county or city (including town and district), month, weekday, theme, and ministry, and keyword search covers venue name, course name, description, tags, and owning organization. Whether a course is open is judged on the server using the current date in Taiwan time, and courses that have not started are labeled as opening soon.

Phone screen recording: zooming and dragging the interactive map.

Character cards are generated one by one from the master workbook by a headless browser launched with Playwright. File names combine the character ID and level, and the cards are regenerated after course data is updated. When the campaign ends, the screens switch automatically to the closing version, and the map and the character collection stay open for browsing. How this kind of repeatable cleanup and checking becomes acceptance evidence on a public-sector project is covered in delivery and maintenance evidence for public-sector projects.

Home page after the campaign ended. The interactive map, character collection, and final ranking remain open for browsing.
Home page after the campaign ended. The interactive map, character collection, and final ranking remain open for browsing.

When this approach does not fit

  • A single organization with a few dozen courses or fewer: a spreadsheet with manual checking is enough.
  • Content that must appear word for word as written, such as legal text or the original wording of a notice: the cleanup rules unify spelling, so this approach does not apply.
  • A campaign with no map and no on-site verification: venue merging and coordinate work can be reduced a great deal, though the header and ID scheme are still needed.

What to prepare before starting

Five things need to be in hand: the list of participating organizations with a contact for each, the header columns to standardize, the campaign period and the featured courses each organization wants to promote, whether the map needs on-site verification, and the basis for the figures used in outward-facing copy. Once all five are ready, the conversation can start at data and platform planning for a cross-organization campaign.

(문의)

Start a project.

세 단계를 거치면 판단 근거가 되는 접근 방식과 예산 범위를 얻을 수 있습니다.

  1. 01첫 미팅 예약: 시간을 선택합니다. 완성된 사양서는 필요하지 않습니다.
  2. 0215~30분 온라인 상담: 접근 방향, 예산 범위, 일정 초안을 받습니다.
  3. 03자료를 검토한 뒤 약 3~5 영업일 안에 견적서 및 납품 사양 명세서를 제공합니다.
이메일
hello@polish-design.com.tw
우편 주소
대만 타이베이시 중산구 즈푸로 191-1호 3층 (104)

첫 미팅 예약

월요일~금요일 16:00–18:00온라인 30분

먼저 시간대를 선택한 뒤 Google 계정 또는 이메일로 확인합니다. 예약이 확정되면 캘린더에 추가할 수 있습니다.

시간 선택

또는 내용을 먼저 보내기

아직 시간을 정하지 않았다면 프로젝트 내용을 먼저 남겨 주세요. 담당자가 이메일로 회신합니다. 전송 후 이어서 예약할 수 있습니다.

추가 정보(선택): 서비스 항목, 현재 단계, 기존 링크, 알게 된 경로

입력한 정보는 이번 프로젝트 검토에만 사용합니다.

ISO/IEC 27001:2022 인증서

(Certificate)

ISO/IEC 27001:2022

인증 기관
ARES International Certification
인증 범위
인터랙티브 몰입형 3D 시스템의 개발 프로세스, 그리고 네트워크 및 인프라의 운영·관리.

인증 기관 웹사이트에서 확인